@tianshu-ai/tianshu 0.4.21 → 0.4.23

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.
Files changed (26) hide show
  1. package/package.json +1 -1
  2. package/packages/server/builtinConfig/plugins/web-search/manifest.json +5 -53
  3. package/packages/server/builtinConfig/plugins/web-search/skills/web-search-howto.md +4 -7
  4. package/packages/web/dist/assets/{bundle-web-hHh7gz2L.js → bundle-web-B7eyKI4Y.js} +1 -1
  5. package/packages/web/dist/assets/index-D97NmBlG.css +2 -0
  6. package/packages/web/dist/assets/{index-B6oq6ed_.js → index-GoKNQUL6.js} +4 -4
  7. package/packages/web/dist/index.html +2 -2
  8. package/plugins/web-search/dist/server.d.ts.map +1 -1
  9. package/plugins/web-search/dist/server.js +18 -56
  10. package/plugins/web-search/dist/server.js.map +1 -1
  11. package/plugins/web-search/dist/tools/index.d.ts +2 -2
  12. package/plugins/web-search/dist/tools/index.d.ts.map +1 -1
  13. package/plugins/web-search/dist/tools/index.js +1 -1
  14. package/plugins/web-search/dist/tools/index.js.map +1 -1
  15. package/plugins/web-search/dist/tools/providers.d.ts +15 -20
  16. package/plugins/web-search/dist/tools/providers.d.ts.map +1 -1
  17. package/plugins/web-search/dist/tools/providers.js +24 -248
  18. package/plugins/web-search/dist/tools/providers.js.map +1 -1
  19. package/plugins/web-search/dist/tools/web-search.d.ts +4 -25
  20. package/plugins/web-search/dist/tools/web-search.d.ts.map +1 -1
  21. package/plugins/web-search/dist/tools/web-search.js +48 -203
  22. package/plugins/web-search/dist/tools/web-search.js.map +1 -1
  23. package/plugins/web-search/manifest.json +5 -53
  24. package/plugins/web-search/package.json +1 -1
  25. package/plugins/web-search/skills/web-search-howto.md +4 -7
  26. package/packages/web/dist/assets/index-DWOCI_kD.css +0 -2
@@ -1,34 +1,13 @@
1
1
  import type { AgentTool } from "@tianshu-ai/plugin-sdk";
2
+ import { type HostedBackend } from "./providers.js";
2
3
  import { ProviderHealth } from "./health.js";
3
- /** Which search scheme the operator picked. The plugin supports
4
- * two key-free schemes (hosted MCP + self-hosted SearXNG) and two
5
- * key-based ones (Tavily + Brave) kept from the original plugin. */
6
- export type SearchScheme = "hosted" | "searxng" | "tavily" | "brave";
7
4
  export interface WebSearchPluginConfig {
8
- /** Operator's chosen scheme. Defaults to "hosted" (key-free). */
9
- scheme?: SearchScheme;
10
- /** Backend for the hosted MCP scheme. */
11
- hostedBackend?: "exa" | "parallel";
12
- /** Optional key for the hosted backend (higher limits; not
13
- * required — the free tier works anonymously). */
14
- exaApiKey?: string;
15
- parallelApiKey?: string;
16
- /** Base URL of a self-hosted SearXNG instance. */
17
- searxngBaseUrl?: string;
18
- tavilyApiKey?: string;
19
- braveApiKey?: string;
5
+ /** Which hosted MCP endpoint to query. Default "exa". */
6
+ backend?: HostedBackend;
20
7
  /** Optional default timeout override (ms). 8000 if unset. */
21
8
  timeoutMs?: number;
22
9
  }
23
10
  export declare function buildWebSearchTool(cfg: WebSearchPluginConfig, health: ProviderHealth): AgentTool;
24
- /** Read raw `pluginConfig` (an opaque Record) into the typed
25
- * shape this plugin actually uses. Plugin's `activate()` calls
26
- * this once at startup. */
11
+ /** Read raw `pluginConfig` into the typed shape. */
27
12
  export declare function readWebSearchConfig(raw: unknown): WebSearchPluginConfig;
28
- /** Resolve the effective scheme. Explicit `scheme` wins; otherwise
29
- * infer from what's configured, preferring the key-free hosted
30
- * scheme so a fresh install works out of the box. */
31
- export declare function effectiveScheme(cfg: WebSearchPluginConfig): SearchScheme;
32
- /** True when the effective scheme has everything it needs to run. */
33
- export declare function isConfigured(cfg: WebSearchPluginConfig): boolean;
34
13
  //# sourceMappingURL=web-search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,wBAAwB,CAAC;AAW1E,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;qEAEqE;AACrE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB,yCAAyC;IACzC,aAAa,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;IACnC;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,qBAAqB,EAC1B,MAAM,EAAE,cAAc,GACrB,SAAS,CAqLX;AAED;;4BAE4B;AAC5B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,CA4BvE;AAED;;sDAEsD;AACtD,wBAAgB,eAAe,CAAC,GAAG,EAAE,qBAAqB,GAAG,YAAY,CAMxE;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAWhE"}
1
+ {"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,qBAAqB,EAC1B,MAAM,EAAE,cAAc,GACrB,SAAS,CA0GX;AAED,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,CAWvE"}
@@ -1,10 +1,8 @@
1
- // `web_search(query, count?, language?, freshness?, provider?)`.
1
+ // `web_search(query, count?, language?, freshness?)`.
2
2
  //
3
- // One tool, two provider adapters, optional fallback. The plugin's
4
- // `activate()` reads its API keys from `ctx.pluginConfig` and
5
- // hands them into `buildWebSearchTool(cfg)` as a closure. The
6
- // host re-activates the plugin when config changes, so the keys
7
- // stay current without per-call config plumbing.
3
+ // One key-free backend: the hosted MCP endpoints. The operator's
4
+ // only choice is which one Exa or Parallel (config `backend`).
5
+ // No API keys, no self-hosting, no scheme selection.
8
6
  //
9
7
  // Tenant config shape:
10
8
  //
@@ -12,33 +10,26 @@
12
10
  // "plugins": {
13
11
  // "web-search": {
14
12
  // "config": {
15
- // "tavilyApiKey": "tvly-...",
16
- // "braveApiKey": "BSA...",
17
- // "preferredProvider": "tavily" | "brave" // optional
13
+ // "backend": "exa" | "parallel", // default "exa"
14
+ // "timeoutMs": 8000 // optional
18
15
  // }
19
16
  // }
20
17
  // }
21
18
  // }
22
- //
23
- // If both keys are configured we prefer `preferredProvider` (or
24
- // "tavily" by default) and fall back to the other one ONLY when
25
- // the first returns a clearly transient error (network reset, 5xx,
26
- // 429, or zero results when both providers are available). Bad
27
- // keys (401/403) don't trigger fallback — that's a config problem
28
- // the user needs to fix, not a runtime hiccup.
29
19
  import { Type } from "typebox";
30
- import { braveProvider, hostedProvider, searxngProvider, tavilyProvider, } from "./providers.js";
20
+ import { hostedProvider, } from "./providers.js";
31
21
  export function buildWebSearchTool(cfg, health) {
22
+ const backend = cfg.backend ?? "exa";
32
23
  return {
33
24
  schema: {
34
25
  name: "web_search",
35
26
  description: "Search the web for up-to-date information. Returns a JSON " +
36
- "array of `{ title, url, content, publishedDate }` objects, " +
37
- "ranked by the underlying provider. Backed by Tavily or " +
38
- "Brave Search depending on which API key the host has " +
39
- "configured. Use this for current events, recent docs, " +
40
- "anything that may have changed since training. Don't loop " +
41
- "many tiny searches \u2014 refine the query and increase `count`.",
27
+ "array of `{ title, url, content, publishedDate }` objects. " +
28
+ "Key-free \u2014 backed by a hosted search endpoint (Exa or " +
29
+ "Parallel, chosen by the host). Use this for current events, " +
30
+ "recent docs, anything that may have changed since training. " +
31
+ "Don't loop many tiny searches \u2014 refine the query and " +
32
+ "increase `count`. Use web_fetch to read a result's full page.",
42
33
  parameters: Type.Object({
43
34
  query: Type.String({
44
35
  description: "Free-text search query, 1-300 chars.",
@@ -49,8 +40,7 @@ export function buildWebSearchTool(cfg, health) {
49
40
  maximum: 20,
50
41
  })),
51
42
  language: Type.Optional(Type.String({
52
- description: "Language hint, ISO 639-1 or locale (e.g. \"zh-CN\", \"en\"). " +
53
- "Only applied by providers that accept it.",
43
+ description: "Language hint, ISO 639-1 or locale (e.g. \"zh-CN\", \"en\").",
54
44
  })),
55
45
  freshness: Type.Optional(Type.Union([
56
46
  Type.Literal("day"),
@@ -58,20 +48,13 @@ export function buildWebSearchTool(cfg, health) {
58
48
  Type.Literal("month"),
59
49
  Type.Literal("year"),
60
50
  ], {
61
- description: "Recency filter. Default is no filter (all results, ranked by relevance).",
62
- })),
63
- provider: Type.Optional(Type.Union([
64
- Type.Literal("hosted"),
65
- Type.Literal("searxng"),
66
- Type.Literal("tavily"),
67
- Type.Literal("brave"),
68
- ], {
69
- description: "Force a specific provider. Default uses the scheme the host configured.",
51
+ description: "Recency filter. Default is no filter (ranked by relevance).",
70
52
  })),
71
53
  }),
72
54
  },
73
55
  available(_ctx) {
74
- return isConfigured(cfg);
56
+ // Always available — the hosted backend needs no credential.
57
+ return true;
75
58
  },
76
59
  async execute(rawArgs, _ctx) {
77
60
  const args = rawArgs;
@@ -85,43 +68,18 @@ export function buildWebSearchTool(cfg, health) {
85
68
  text: "query too long (max 300 chars). Trim or split into separate searches.",
86
69
  };
87
70
  }
88
- const fullOrder = providerOrder(cfg, args.provider);
89
- if (fullOrder.length === 0) {
90
- return {
91
- ok: false,
92
- text: "web_search is not configured. Open Settings → Plugins → Web " +
93
- "Search and pick a scheme: \"hosted\" (key-free, Exa/Parallel), " +
94
- "\"searxng\" (set your instance URL), or \"tavily\"/\"brave\" " +
95
- "(set an API key).",
96
- };
97
- }
98
- // Apply health cache: skip providers we already know are
99
- // dead (bad key). The agent gets to see the cached reason
100
- // in the error trail, so a stale cache shows up loudly.
101
- const skipped = [];
102
- const order = fullOrder.filter(({ provider }) => {
103
- const dead = health.isDead(provider.name);
104
- if (dead) {
105
- skipped.push({
106
- provider: provider.name,
107
- status: dead.status,
108
- message: `cached as dead since ${new Date(dead.deadSince).toISOString()}: ${dead.message}`,
109
- });
110
- return false;
111
- }
112
- return true;
113
- });
114
- if (order.length === 0) {
71
+ // Health cache: skip the backend if a prior auth failure
72
+ // parked it (rare for the free endpoints, but the trail is
73
+ // useful if it ever happens).
74
+ const dead = health.isDead("hosted");
75
+ if (dead) {
115
76
  return {
116
77
  ok: false,
117
- text: `web_search: every configured provider is in the dead-cache. ` +
118
- `Update the bad key(s) and click "Reset health cache" in ` +
119
- `Settings Plugins Web Search, or PATCH ` +
120
- `/api/p/web-search/health/reset.\n\nDead providers:\n` +
121
- skipped
122
- .map((s) => `- ${s.provider} (status ${s.status}): ${s.message}`)
123
- .join("\n"),
124
- data: { skipped },
78
+ text: `web_search: the hosted backend is in the dead-cache ` +
79
+ `(status ${dead.status}: ${dead.message}). Reset it in ` +
80
+ `Settings \u2192 Plugins \u2192 Web Search or POST ` +
81
+ `/api/p/web-search/health/reset.`,
82
+ data: { dead },
125
83
  };
126
84
  }
127
85
  const opts = {
@@ -130,148 +88,36 @@ export function buildWebSearchTool(cfg, health) {
130
88
  freshness: args.freshness,
131
89
  timeoutMs: cfg.timeoutMs ?? 8000,
132
90
  };
133
- const errors = [...skipped];
134
- for (const { provider, key } of order) {
135
- const out = await provider.search(query, key, opts);
136
- if ("results" in out) {
137
- if (out.results.length === 0 && order.length > 1) {
138
- // Empty isn't an error per se, but if we have a fallback
139
- // it's worth one more shot — small queries sometimes
140
- // return nothing on Brave but plenty on Tavily.
141
- errors.push({
142
- provider: provider.name,
143
- status: 200,
144
- message: "zero results",
145
- });
146
- continue;
147
- }
148
- return formatSuccess(provider.name, query, out.results, errors);
149
- }
150
- const e = out.error;
151
- errors.push(e);
152
- // Auth errors: park the provider in the health cache so
153
- // future calls skip it without paying the round-trip.
154
- // Only auth gets cached — 5xx / network / 429 are usually
155
- // transient and would bake a bad cache entry.
156
- if (e.status === 401 || e.status === 403) {
157
- health.markDead(provider.name, e.status, e.message);
158
- // Don't fall back on auth errors — the operator needs to
159
- // fix the key. (Falling back to a probably-also-broken
160
- // sibling key just papers over the real problem.)
161
- break;
162
- }
91
+ const out = await hostedProvider.search(query, backend, opts);
92
+ if ("results" in out) {
93
+ return formatSuccess(backend, query, out.results);
94
+ }
95
+ const e = out.error;
96
+ if (e.status === 401 || e.status === 403) {
97
+ health.markDead("hosted", e.status, e.message);
163
98
  }
164
99
  return {
165
100
  ok: false,
166
- text: formatFailure(query, errors),
167
- data: { query, errors },
101
+ text: formatFailure(query, e),
102
+ data: { query, error: e },
168
103
  };
169
104
  },
170
105
  };
171
106
  }
172
- /** Read raw `pluginConfig` (an opaque Record) into the typed
173
- * shape this plugin actually uses. Plugin's `activate()` calls
174
- * this once at startup. */
107
+ /** Read raw `pluginConfig` into the typed shape. */
175
108
  export function readWebSearchConfig(raw) {
176
109
  if (!raw || typeof raw !== "object")
177
110
  return {};
178
111
  const r = raw;
179
- const str = (k) => typeof r[k] === "string" && r[k] ? r[k] : undefined;
180
- const scheme = r.scheme === "hosted" ||
181
- r.scheme === "searxng" ||
182
- r.scheme === "tavily" ||
183
- r.scheme === "brave"
184
- ? r.scheme
185
- : undefined;
186
112
  return {
187
- scheme,
188
- hostedBackend: r.hostedBackend === "parallel" || r.hostedBackend === "exa"
189
- ? r.hostedBackend
190
- : undefined,
191
- exaApiKey: str("exaApiKey"),
192
- parallelApiKey: str("parallelApiKey"),
193
- searxngBaseUrl: str("searxngBaseUrl"),
194
- tavilyApiKey: str("tavilyApiKey"),
195
- braveApiKey: str("braveApiKey"),
113
+ backend: r.backend === "parallel" || r.backend === "exa" ? r.backend : undefined,
196
114
  timeoutMs: typeof r.timeoutMs === "number" && Number.isFinite(r.timeoutMs)
197
115
  ? r.timeoutMs
198
116
  : undefined,
199
117
  };
200
118
  }
201
- /** Resolve the effective scheme. Explicit `scheme` wins; otherwise
202
- * infer from what's configured, preferring the key-free hosted
203
- * scheme so a fresh install works out of the box. */
204
- export function effectiveScheme(cfg) {
205
- if (cfg.scheme)
206
- return cfg.scheme;
207
- if (cfg.searxngBaseUrl)
208
- return "searxng";
209
- if (cfg.tavilyApiKey)
210
- return "tavily";
211
- if (cfg.braveApiKey)
212
- return "brave";
213
- return "hosted"; // key-free default
214
- }
215
- /** True when the effective scheme has everything it needs to run. */
216
- export function isConfigured(cfg) {
217
- switch (effectiveScheme(cfg)) {
218
- case "hosted":
219
- return true; // key-free
220
- case "searxng":
221
- return Boolean(cfg.searxngBaseUrl);
222
- case "tavily":
223
- return Boolean(cfg.tavilyApiKey);
224
- case "brave":
225
- return Boolean(cfg.braveApiKey);
226
- }
227
- }
228
- /** Pack the hosted provider's opaque `key` blob (backend + optional
229
- * api key). See hostedProvider in providers.ts. */
230
- function hostedKey(cfg) {
231
- const backend = cfg.hostedBackend ?? "exa";
232
- const apiKey = backend === "parallel" ? cfg.parallelApiKey : cfg.exaApiKey;
233
- return JSON.stringify({ backend, apiKey });
234
- }
235
- /** Decide which providers to try, in order. Returns at most two
236
- * entries (the configured pair, preferred first). */
237
- function providerOrder(cfg, override) {
238
- // Build the entry for a single scheme, or null when that scheme
239
- // isn't usable (missing credential).
240
- const entryFor = (scheme) => {
241
- switch (scheme) {
242
- case "hosted":
243
- return { provider: hostedProvider, key: hostedKey(cfg) };
244
- case "searxng":
245
- return cfg.searxngBaseUrl
246
- ? { provider: searxngProvider, key: cfg.searxngBaseUrl }
247
- : null;
248
- case "tavily":
249
- return cfg.tavilyApiKey
250
- ? { provider: tavilyProvider, key: cfg.tavilyApiKey }
251
- : null;
252
- case "brave":
253
- return cfg.braveApiKey
254
- ? { provider: braveProvider, key: cfg.braveApiKey }
255
- : null;
256
- }
257
- };
258
- // Explicit per-call override: honour it if usable, else fall
259
- // through to the configured scheme.
260
- if (override) {
261
- const e = entryFor(override);
262
- if (e)
263
- return [e];
264
- }
265
- // No cross-scheme fallback: the operator picked a scheme, we use
266
- // it. (Mixing a self-hosted SearXNG with a paid Tavily fallback
267
- // would be surprising.) Return the single effective scheme.
268
- const e = entryFor(effectiveScheme(cfg));
269
- return e ? [e] : [];
270
- }
271
- function formatSuccess(provider, query, results, priorErrors) {
272
- const head = priorErrors.length === 0
273
- ? `${results.length} result${results.length === 1 ? "" : "s"} from ${provider} for "${query}":`
274
- : `${results.length} result${results.length === 1 ? "" : "s"} from ${provider} (after ${priorErrors.length} fallback attempt${priorErrors.length === 1 ? "" : "s"}) for "${query}":`;
119
+ function formatSuccess(backend, query, results) {
120
+ const head = `${results.length} result${results.length === 1 ? "" : "s"} from ${backend} for "${query}":`;
275
121
  const lines = results.map((r, i) => {
276
122
  const date = r.publishedDate ? ` (${r.publishedDate})` : "";
277
123
  const snippet = (r.content ?? "").trim().slice(0, 280);
@@ -280,18 +126,17 @@ function formatSuccess(provider, query, results, priorErrors) {
280
126
  return {
281
127
  ok: true,
282
128
  text: [head, "", ...lines].join("\n"),
283
- data: { query, provider, results },
129
+ data: { query, provider: backend, results },
284
130
  };
285
131
  }
286
- function formatFailure(query, errors) {
287
- const lines = errors.map((e) => `- ${e.provider} (status ${e.status}): ${e.message}`);
132
+ function formatFailure(query, error) {
288
133
  return [
289
- `web_search failed for "${query}". Provider attempts:`,
290
- ...lines,
134
+ `web_search failed for "${query}":`,
135
+ `- ${error.provider} (status ${error.status}): ${error.message}`,
291
136
  "",
292
- "If this is a config problem (status 401 / 403), update the key " +
293
- "in tenant config under `plugins.web-search.config`. If it's a " +
294
- "transient network error, retry the query.",
137
+ "The hosted endpoint may be rate-limiting or temporarily down. " +
138
+ "Retry shortly, or switch the backend (Exa \u2194 Parallel) in " +
139
+ "Settings \u2192 Plugins \u2192 Web Search.",
295
140
  ].join("\n");
296
141
  }
297
142
  //# sourceMappingURL=web-search.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "id": "web-search",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "displayName": "Web Search",
5
- "description": "Web search + single-page fetch for agents. Pick a scheme: key-free hosted MCP (Exa/Parallel), self-hosted SearXNG, or keyed Tavily/Brave. web_fetch works with no config.",
5
+ "description": "Key-free web search + single-page fetch for agents. Search runs against a hosted endpoint (Exa or Parallel) with no API key. web_fetch reads a page to markdown, also no config.",
6
6
  "author": "tianshu-ai",
7
7
  "license": "Apache-2.0",
8
8
  "permissions": ["network.external"],
@@ -26,63 +26,15 @@
26
26
  "configSchema": {
27
27
  "fields": [
28
28
  {
29
- "key": "scheme",
30
- "label": "Search scheme",
31
- "kind": "select",
32
- "default": "hosted",
33
- "options": [
34
- { "label": "Hosted MCP (key-free: Exa / Parallel)", "value": "hosted" },
35
- { "label": "SearXNG (self-hosted)", "value": "searxng" },
36
- { "label": "Tavily (API key)", "value": "tavily" },
37
- { "label": "Brave (API key)", "value": "brave" }
38
- ],
39
- "description": "Which backend web_search uses. \"hosted\" needs no key (uses Exa/Parallel free MCP endpoints). \"searxng\" needs a base URL below. \"tavily\"/\"brave\" need the matching API key. web_fetch always works regardless of this setting."
40
- },
41
- {
42
- "key": "hostedBackend",
43
- "label": "Hosted backend",
29
+ "key": "backend",
30
+ "label": "Search backend",
44
31
  "kind": "select",
45
32
  "default": "exa",
46
33
  "options": [
47
34
  { "label": "Exa", "value": "exa" },
48
35
  { "label": "Parallel", "value": "parallel" }
49
36
  ],
50
- "description": "Only used when scheme = hosted. Which free MCP endpoint to query. Both work anonymously; add a key below only if you have one and want higher limits."
51
- },
52
- {
53
- "key": "searxngBaseUrl",
54
- "label": "SearXNG base URL",
55
- "kind": "string",
56
- "placeholder": "https://searx.example.com",
57
- "description": "Only used when scheme = searxng. Base URL of your SearXNG instance (its JSON API must be enabled: `search.formats: [json]` in settings.yml). No API key needed."
58
- },
59
- {
60
- "key": "exaApiKey",
61
- "label": "Exa API key (optional)",
62
- "kind": "secret",
63
- "placeholder": "exa-...",
64
- "description": "Optional. Only used when scheme = hosted and backend = Exa. Raises limits; the free endpoint works without it. Stored under <tenant>/secrets/, never returned to the browser."
65
- },
66
- {
67
- "key": "parallelApiKey",
68
- "label": "Parallel API key (optional)",
69
- "kind": "secret",
70
- "placeholder": "...",
71
- "description": "Optional. Only used when scheme = hosted and backend = Parallel. Raises limits; the free endpoint works without it."
72
- },
73
- {
74
- "key": "tavilyApiKey",
75
- "label": "Tavily API key",
76
- "kind": "secret",
77
- "placeholder": "tvly-...",
78
- "description": "Only used when scheme = tavily. Sign up at tavily.com (free tier 1000 searches/month). Stored under <tenant>/secrets/, never returned to the browser."
79
- },
80
- {
81
- "key": "braveApiKey",
82
- "label": "Brave Search API key",
83
- "kind": "secret",
84
- "placeholder": "BSA...",
85
- "description": "Only used when scheme = brave. Get a free key at api-dashboard.search.brave.com (2000/month)."
37
+ "description": "Which hosted endpoint web_search queries. Both are key-free (anonymous free tier). Exa returns highlighted excerpts; Parallel returns ranked results. web_fetch is unaffected."
86
38
  },
87
39
  {
88
40
  "key": "timeoutMs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tianshu-builtin/plugin-web-search",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "private": true,
5
5
  "description": "Web search + fetch for tianshu agents. Schemes: key-free hosted MCP (Exa/Parallel), self-hosted SearXNG, or keyed Tavily/Brave.",
6
6
  "type": "module",
@@ -9,10 +9,9 @@ scope: worker
9
9
  This plugin gives you two tools:
10
10
 
11
11
  - **`web_search`** — returns a JSON array of `{title, url,
12
- content, publishedDate}` results. The host picks the backend
13
- scheme (you don't): key-free hosted MCP (Exa/Parallel),
14
- a self-hosted SearXNG instance, or Tavily/Brave. Same result
15
- shape regardless.
12
+ content, publishedDate}` results. Key-free: runs against a
13
+ hosted endpoint (Exa or Parallel; the host picks which). You
14
+ don't configure or choose anything at call time.
16
15
  - **`web_fetch`** — fetches ONE URL and returns its readable
17
16
  body as markdown or text. No API key, no JavaScript. Use it
18
17
  to read a page you got from a search result.
@@ -43,9 +42,7 @@ snippet is insufficient.
43
42
  Biases engines toward language-specific sources. Skip this
44
43
  for technical English-language queries; technical content is
45
44
  usually English regardless of locale.
46
- - `provider`: force `"hosted"`, `"searxng"`, `"tavily"`, or
47
- `"brave"` if you want a specific backend. Default is the
48
- scheme the host configured. Usually leave it unset.
45
+
49
46
 
50
47
  ## Anti-patterns
51
48