dsh-free-search 0.6.5 → 0.6.6
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/lib/client.js +2 -2
- package/lib/index.js +32 -6
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -290,7 +290,7 @@ window.__ModuleLoader__.load({
|
|
|
290
290
|
};
|
|
291
291
|
const tt = (lang) => I18N[lang === "en" ? "en" : "zh"];
|
|
292
292
|
// 当前插件版本(与 lib/index.js 的 PLUGIN_VERSION 保持一致)
|
|
293
|
-
const PLUGIN_VERSION = "0.6.
|
|
293
|
+
const PLUGIN_VERSION = "0.6.6";
|
|
294
294
|
const ENGINES = [
|
|
295
295
|
{ id: "auto", label: "Auto · 智能路由", badge: "AUTO", link: null },
|
|
296
296
|
{ id: "multi", label: "Multi Search · 多引擎", badge: "MULTI", link: null },
|
|
@@ -647,7 +647,7 @@ window.__ModuleLoader__.load({
|
|
|
647
647
|
setTestResult({
|
|
648
648
|
ok: true,
|
|
649
649
|
count: sources.length,
|
|
650
|
-
engine: result.value.provider ?? provider,
|
|
650
|
+
engine: result.value.provider === "multi_search" ? "multi" : (result.value.provider ?? provider),
|
|
651
651
|
content: result.value.content ?? "",
|
|
652
652
|
sample: sources[0]?.title ?? "",
|
|
653
653
|
});
|
package/lib/index.js
CHANGED
|
@@ -61,6 +61,9 @@ const ALL_ENGINES = ["ddg", "ddg-lite", "bing", "searxng", "anysearch", "exa", "
|
|
|
61
61
|
// 支持 time_range 过滤的引擎
|
|
62
62
|
const TIME_ENGINES = ["tavily", "exa", "keenable", "firecrawl", "parallel", "searxng", "ddg", "ddg-lite", "baidu", "doubao"];
|
|
63
63
|
|
|
64
|
+
// 虚拟搜索模式:不是单个引擎,而是 provider.search 内部的路由/并发策略
|
|
65
|
+
const SEARCH_MODES = ["auto", "multi"];
|
|
66
|
+
|
|
64
67
|
const DEFAULT_FALLBACK_ORDER = ["exa", "tavily", "keenable", "firecrawl", "parallel", "perplexity", "serpbase", "deepseek-official", "you", "baidu", "kimi", "aliyun", "doubao", "bing", "anysearch", "ddg", "ddg-lite", "searxng"];
|
|
65
68
|
|
|
66
69
|
function normalizeDisabledEngines(value) {
|
|
@@ -118,7 +121,7 @@ function routeEngines(query, { timeRange, disabledEngines = [], fallbackOrder =
|
|
|
118
121
|
}
|
|
119
122
|
|
|
120
123
|
// 当前插件版本(发布时与 package.json 同步)
|
|
121
|
-
const PLUGIN_VERSION = "0.6.
|
|
124
|
+
const PLUGIN_VERSION = "0.6.6";
|
|
122
125
|
// 检查更新的 npm registry 元数据地址(dsh-free-search 是 npmjs 上的公开包)
|
|
123
126
|
const NPM_REGISTRY_URL = "https://registry.npmjs.org/dsh-free-search/latest";
|
|
124
127
|
const PLUGIN_NPM_URL = "https://www.npmjs.com/package/dsh-free-search";
|
|
@@ -2036,8 +2039,11 @@ function makeBridgeRoutes(settings, search, testEngine, getCredentials) {
|
|
|
2036
2039
|
}
|
|
2037
2040
|
const maxResults = Math.min(Math.max(Number(request.maxResults) || 5, 1), 10);
|
|
2038
2041
|
const timeRange = parseTimeRange(request.timeRange);
|
|
2039
|
-
// 指定 engine
|
|
2040
|
-
|
|
2042
|
+
// 指定 engine:直测该引擎本身(不走回退链),报告它自己的可用性。
|
|
2043
|
+
// auto / multi 是虚拟模式,没有"单引擎本身"可测 → 交给下面的 provider.search,
|
|
2044
|
+
// 真实跑一遍路由/并发链路(否则设置页「测试引擎」会对它们报 unknown engine)。
|
|
2045
|
+
const engineIsMode = typeof request.engine === "string" && SEARCH_MODES.includes(request.engine);
|
|
2046
|
+
if (typeof request.engine === "string" && request.engine.length > 0 && !engineIsMode) {
|
|
2041
2047
|
if (typeof testEngine !== "function") {
|
|
2042
2048
|
return { ok: false, code: "search-unavailable", message: "engine test is not wired" };
|
|
2043
2049
|
}
|
|
@@ -3056,7 +3062,7 @@ function apply(ctx, config) {
|
|
|
3056
3062
|
parameters: {
|
|
3057
3063
|
engines: {
|
|
3058
3064
|
type: "array",
|
|
3059
|
-
description: "Which engines to test (default: all). Options: ddg, ddg-lite, bing, searxng, anysearch, exa, tavily, keenable, firecrawl, parallel, perplexity, serpbase, deepseek-official, you, baidu, kimi, aliyun, doubao.",
|
|
3065
|
+
description: "Which engines to test (default: all enabled engines). Options: ddg, ddg-lite, bing, searxng, anysearch, exa, tavily, keenable, firecrawl, parallel, perplexity, serpbase, deepseek-official, you, baidu, kimi, aliyun, doubao; the virtual modes auto and multi are also accepted and run the real routing/concurrent path.",
|
|
3060
3066
|
items: { type: "string" },
|
|
3061
3067
|
},
|
|
3062
3068
|
query: {
|
|
@@ -3089,7 +3095,8 @@ function apply(ctx, config) {
|
|
|
3089
3095
|
render(args, value) {
|
|
3090
3096
|
const lines = value.results.map((r) => {
|
|
3091
3097
|
if (r.status === "ok") {
|
|
3092
|
-
|
|
3098
|
+
const via = r.engineUsed && r.engineUsed !== r.engine ? ` via ${r.engineUsed}` : "";
|
|
3099
|
+
return `- ${r.engine}: OK (${r.results} results${via}${r.sampleTitle ? `, e.g. "${r.sampleTitle.slice(0, 40)}"` : ""})`;
|
|
3093
3100
|
}
|
|
3094
3101
|
if (r.status === "disabled") return `- ${r.engine}: DISABLED`;
|
|
3095
3102
|
return `- ${r.engine}: FAIL - ${r.error}`;
|
|
@@ -3103,7 +3110,7 @@ function apply(ctx, config) {
|
|
|
3103
3110
|
const disabled = new Set(normalizeDisabledEngines(current().disabledEngines));
|
|
3104
3111
|
const explicit = Array.isArray(args.engines) && args.engines.length > 0;
|
|
3105
3112
|
const engines = explicit
|
|
3106
|
-
? args.engines.filter((engine) => ALL_ENGINES.includes(engine))
|
|
3113
|
+
? args.engines.filter((engine) => ALL_ENGINES.includes(engine) || SEARCH_MODES.includes(engine))
|
|
3107
3114
|
: enabledEngines(current().disabledEngines, current().fallbackOrder);
|
|
3108
3115
|
const results = [];
|
|
3109
3116
|
for (const engine of engines) {
|
|
@@ -3111,6 +3118,25 @@ function apply(ctx, config) {
|
|
|
3111
3118
|
results.push({ engine, status: "disabled" });
|
|
3112
3119
|
continue;
|
|
3113
3120
|
}
|
|
3121
|
+
// 虚拟模式(auto/multi):走 provider.search 真实路由/并发,报告实际生效的引擎
|
|
3122
|
+
if (SEARCH_MODES.includes(engine)) {
|
|
3123
|
+
try {
|
|
3124
|
+
const r = await provider.search({ query: args.query, maxResults: 2, engine });
|
|
3125
|
+
const sources = r.sources ?? [];
|
|
3126
|
+
if (sources.length === 0) {
|
|
3127
|
+
results.push({ engine, status: "fail", error: "0 results" });
|
|
3128
|
+
} else {
|
|
3129
|
+
const item = { engine, status: "ok", results: sources.length, engineUsed: r.provider ?? r.engine ?? engine };
|
|
3130
|
+
if (sources[0]?.title) item.sampleTitle = String(sources[0].title);
|
|
3131
|
+
if (sources[0]?.url) item.sampleUrl = String(sources[0].url);
|
|
3132
|
+
if (r.content) item.note = String(r.content);
|
|
3133
|
+
results.push(item);
|
|
3134
|
+
}
|
|
3135
|
+
} catch (error) {
|
|
3136
|
+
results.push({ engine, status: "fail", error: error instanceof Error ? error.message : String(error) });
|
|
3137
|
+
}
|
|
3138
|
+
continue;
|
|
3139
|
+
}
|
|
3114
3140
|
const r = await runEngineTest(engine, args.query);
|
|
3115
3141
|
if (r.ok) {
|
|
3116
3142
|
const item = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-free-search",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.6",
|
|
4
4
|
"description": "Free web search for DeepSeek Harness: 18 engines (Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel keyless; Perplexity/SerpBase/DeepSeek/You.com/Baidu/Kimi/Aliyun/Doubao with key) + auto smart routing + global engine enable/disable & fallback priority + multi mode (parallel top-3 merge) + multi_search cross-source tool + time filtering + platform search + web_fetch, with web settings UI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|