dsh-free-search 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.
- package/README.md +24 -0
- package/lib/client.js +75 -6
- package/lib/index.js +42 -7
- package/package.json +67 -67
package/README.md
CHANGED
|
@@ -43,6 +43,8 @@ dsh 默认的搜索 provider 依赖 DeepSeek 官方 API key(`DEEPSEEK_API_KEY`
|
|
|
43
43
|
- **平台搜索(platform_search)** —— 搜 GitHub / V2EX / B站 / Reddit / Hacker News / Stack Overflow / 维基百科 / npm(公开 API,零依赖)
|
|
44
44
|
- **干净集成** —— 实现官方 `WebSearchProvider` seam 接口,与官方插件共存
|
|
45
45
|
|
|
46
|
+
如果这个插件帮到了你,欢迎给仓库点个 ⭐([GitHub](https://github.com/DDDMUC/dsh-free-search))——星标是开发者继续维护的最大动力,感谢支持!
|
|
47
|
+
|
|
46
48
|
### 引擎列表
|
|
47
49
|
|
|
48
50
|
| id | 引擎 | 费用 | 说明 |
|
|
@@ -87,6 +89,16 @@ dsh plugin --profile web add /path/to/dsh-free-search
|
|
|
87
89
|
dsh web
|
|
88
90
|
```
|
|
89
91
|
|
|
92
|
+
#### 姊妹插件:dsh-preset-workbench(预设工作台)
|
|
93
|
+
|
|
94
|
+
同作者的**姊妹插件**:在设置页里可视化创建/编辑 Agent 预设——分段提示词、15 项能力开关、内置「鲸鱼娘 / 梁神模式」模板,不用手写 YAML。两者搭配:**free-search 解决"AI 联网搜索"、preset-workbench 解决"AI 人设能力编排"**,都是纯免费、开箱即用。
|
|
95
|
+
|
|
96
|
+
- 仓库:<https://github.com/DDDMUC/dsh-preset-workbench>
|
|
97
|
+
- 安装:`dsh plugin --profile web add github:DDDMUC/dsh-preset-workbench`
|
|
98
|
+
- 用法:设置 → 预设工作台
|
|
99
|
+
|
|
100
|
+
如果你觉得 preset-workbench 也有用,同样欢迎给它的仓库点个 ⭐。🙏
|
|
101
|
+
|
|
90
102
|
#### 依赖说明
|
|
91
103
|
|
|
92
104
|
插件对 `@deepseek-ai/dsh-settings` 和 `@deepseek-ai/dsh-tools` 使用 `peerDependencies`,这是刻意的:DSH 运行时必须使用安装树中的唯一实例。请通过 `dsh plugin --profile <profile> add ...` 安装插件,不要把 DSH 核心包复制进 profile 的本地 `node_modules`;重复副本会导致工具调度器失效。
|
|
@@ -284,6 +296,8 @@ This plugin provides multiple free search engines with automatic fallback, compl
|
|
|
284
296
|
- **Platform Search (`platform_search`)** — Search GitHub / V2EX / Bilibili / Reddit / Hacker News / Stack Overflow / Wikipedia / npm (public APIs, zero extra dependencies)
|
|
285
297
|
- **Clean Integration** — Implements the official `WebSearchProvider` seam interface, coexisting seamlessly with official plugins
|
|
286
298
|
|
|
299
|
+
If this plugin has been helpful, a ⭐ on [GitHub](https://github.com/DDDMUC/dsh-free-search) would mean a lot — it's the biggest motivation for the developer to keep maintaining it. Thank you!
|
|
300
|
+
|
|
287
301
|
### Supported Engines
|
|
288
302
|
|
|
289
303
|
| id | Engine | Cost | Description |
|
|
@@ -328,6 +342,16 @@ Then restart:
|
|
|
328
342
|
dsh web
|
|
329
343
|
```
|
|
330
344
|
|
|
345
|
+
#### Sister Plugin: dsh-preset-workbench
|
|
346
|
+
|
|
347
|
+
A **sister plugin** by the same author: a **visual workbench for creating/editing agent presets** right inside Settings — sectioned prompts, 15 capability toggles, and built-in "Whale Girl / Liangshen Mode" templates, no YAML needed. Pair them up: **free-search gives your AI web search, preset-workbench shapes its persona & capabilities** — both free and zero-config.
|
|
348
|
+
|
|
349
|
+
- Repo: <https://github.com/DDDMUC/dsh-preset-workbench>
|
|
350
|
+
- Install: `dsh plugin --profile web add github:DDDMUC/dsh-preset-workbench`
|
|
351
|
+
- Usage: Settings → Preset Workbench
|
|
352
|
+
|
|
353
|
+
If preset-workbench is useful to you too, a ⭐ on its repo is always welcome. 🙏
|
|
354
|
+
|
|
331
355
|
#### Dependency Note
|
|
332
356
|
|
|
333
357
|
This plugin intentionally specifies `@deepseek-ai/dsh-settings` and `@deepseek-ai/dsh-tools` as `peerDependencies`: the DSH runtime must use a single instance from the installation tree. Always install the plugin using `dsh plugin --profile <profile> add ...`. Do **not** copy DSH core packages into a profile-local `node_modules`, as duplicate copies can break the tool scheduler.
|
package/lib/client.js
CHANGED
|
@@ -122,6 +122,23 @@ window.__ModuleLoader__.load({
|
|
|
122
122
|
upgradeLinkMode: "(本地开发模式,升级请用 git pull)",
|
|
123
123
|
upgradeDone: (l) => `升级到 v${l} 完成,重启 dsh 后生效`,
|
|
124
124
|
upgradeFailed: (m) => `升级失败:${m}`,
|
|
125
|
+
safeSearchLabel: "安全搜索过滤 (adlt)",
|
|
126
|
+
safeSearchOff: "关闭 —— 引擎默认(不加参数)",
|
|
127
|
+
safeSearchModerate: "中等 —— Bing 默认",
|
|
128
|
+
safeSearchStrict: "严格",
|
|
129
|
+
safeSearchHint: "作用于 Bing(adlt)、DuckDuckGo HTML / Lite(adlt 等级)。如遇引擎自带过滤可在此调整。",
|
|
130
|
+
bingMarketLabel: "Bing 市场(本地化结果)",
|
|
131
|
+
bingMarketHint: "Bing 的 mkt + Accept-Language 跟随此设置。例如 ru-RU 会让西里尔查询返回俄语结果。",
|
|
132
|
+
marketZhCN: "zh-CN —— 中国大陆(默认)",
|
|
133
|
+
marketZhTW: "zh-TW —— 台湾",
|
|
134
|
+
marketEnUS: "en-US —— 美国",
|
|
135
|
+
marketEnGB: "en-GB —— 英国",
|
|
136
|
+
marketRuRU: "ru-RU —— 俄罗斯",
|
|
137
|
+
marketJaJP: "ja-JP —— 日本",
|
|
138
|
+
marketDeDE: "de-DE —— 德国",
|
|
139
|
+
marketFrFR: "fr-FR —— 法国",
|
|
140
|
+
marketEsES: "es-ES —— 西班牙",
|
|
141
|
+
marketKoKR: "ko-KR —— 韩国",
|
|
125
142
|
},
|
|
126
143
|
en: {
|
|
127
144
|
description: "Free web search — no API key needed (Bing / DuckDuckGo / AnySearch / Exa / Tavily / Keenable)",
|
|
@@ -168,11 +185,28 @@ window.__ModuleLoader__.load({
|
|
|
168
185
|
upgradeLinkMode: "(local dev install - use git pull to update)",
|
|
169
186
|
upgradeDone: (l) => `Upgraded to v${l} - restart dsh to apply`,
|
|
170
187
|
upgradeFailed: (m) => `Upgrade failed: ${m}`,
|
|
188
|
+
safeSearchLabel: "Safe search filter (adlt)",
|
|
189
|
+
safeSearchOff: "Off - engine default (no filtering)",
|
|
190
|
+
safeSearchModerate: "Moderate - Bing default",
|
|
191
|
+
safeSearchStrict: "Strict",
|
|
192
|
+
safeSearchHint: "Applies to bing (adlt), ddg, ddg-lite (adlt degree). If you see the engine's own filtering, adjust here.",
|
|
193
|
+
bingMarketLabel: "Bing market (localized results)",
|
|
194
|
+
bingMarketHint: "Bing's mkt + Accept-Language follow this. e.g. ru-RU returns Russian results for Cyrillic queries.",
|
|
195
|
+
marketZhCN: "zh-CN - China (default)",
|
|
196
|
+
marketZhTW: "zh-TW - Taiwan",
|
|
197
|
+
marketEnUS: "en-US - United States",
|
|
198
|
+
marketEnGB: "en-GB - United Kingdom",
|
|
199
|
+
marketRuRU: "ru-RU - Russia",
|
|
200
|
+
marketJaJP: "ja-JP - Japan",
|
|
201
|
+
marketDeDE: "de-DE - Germany",
|
|
202
|
+
marketFrFR: "fr-FR - France",
|
|
203
|
+
marketEsES: "es-ES - Spain",
|
|
204
|
+
marketKoKR: "ko-KR - Korea",
|
|
171
205
|
},
|
|
172
206
|
};
|
|
173
207
|
const tt = (lang) => I18N[lang === "en" ? "en" : "zh"];
|
|
174
208
|
// 当前插件版本(与 lib/index.js 的 PLUGIN_VERSION 保持一致)
|
|
175
|
-
const PLUGIN_VERSION = "0.4.
|
|
209
|
+
const PLUGIN_VERSION = "0.4.23";
|
|
176
210
|
const ENGINES = [
|
|
177
211
|
{ id: "ddg", label: "DuckDuckGo · HTML", badge: "FREE", link: "https://duckduckgo.com" },
|
|
178
212
|
{ id: "ddg-lite", label: "DuckDuckGo · Lite", badge: "FREE", link: "https://duckduckgo.com" },
|
|
@@ -274,6 +308,7 @@ window.__ModuleLoader__.load({
|
|
|
274
308
|
const [state, setState] = react.useState({ status: "loading" });
|
|
275
309
|
const [provider, setProvider] = react.useState("bing");
|
|
276
310
|
const [safeSearch, setSafeSearch] = react.useState("off");
|
|
311
|
+
const [bingMarket, setBingMarket] = react.useState("zh-CN");
|
|
277
312
|
const [exaKey, setExaKey] = react.useState("");
|
|
278
313
|
const [tavilyKey, setTavilyKey] = react.useState("");
|
|
279
314
|
const [keenableKey, setKeenableKey] = react.useState("");
|
|
@@ -305,6 +340,7 @@ window.__ModuleLoader__.load({
|
|
|
305
340
|
const v = view.value ?? {};
|
|
306
341
|
setProvider(v.provider ?? "ddg");
|
|
307
342
|
setSafeSearch(v.safeSearch === "strict" || v.safeSearch === "moderate" ? v.safeSearch : "off");
|
|
343
|
+
setBingMarket(v.bingMarket === undefined ? "zh-CN" : v.bingMarket);
|
|
308
344
|
setLang(v.lang === "en" ? "en" : "zh");
|
|
309
345
|
setExaKey(v.exaApiKey ?? "");
|
|
310
346
|
setTavilyKey(v.tavilyApiKey ?? "");
|
|
@@ -386,6 +422,7 @@ window.__ModuleLoader__.load({
|
|
|
386
422
|
ops.push({ op: "set", path: ["lang"], value: lang });
|
|
387
423
|
ops.push({ op: "set", path: ["keyStorage"], value: keyStorage });
|
|
388
424
|
ops.push({ op: "set", path: ["safeSearch"], value: safeSearch });
|
|
425
|
+
ops.push({ op: "set", path: ["bingMarket"], value: bingMarket });
|
|
389
426
|
if (keyStorage !== "credentials") {
|
|
390
427
|
// settings 模式:key 仍写 settings.yaml(旧行为)
|
|
391
428
|
for (const [field, value] of keyFields) {
|
|
@@ -578,7 +615,7 @@ react_jsx_runtime.jsx("div", {
|
|
|
578
615
|
children: [
|
|
579
616
|
react_jsx_runtime.jsx("div", {
|
|
580
617
|
className: "dshfs-label",
|
|
581
|
-
children:
|
|
618
|
+
children: t.safeSearchLabel,
|
|
582
619
|
}),
|
|
583
620
|
react_jsx_runtime.jsx("select", {
|
|
584
621
|
className: "dshfs-select",
|
|
@@ -587,14 +624,46 @@ react_jsx_runtime.jsx("div", {
|
|
|
587
624
|
disabled: !ready || saving,
|
|
588
625
|
onChange: (e) => setSafeSearch(e.target.value),
|
|
589
626
|
children: [
|
|
590
|
-
react_jsx_runtime.jsx("option", { value: "off", children:
|
|
591
|
-
react_jsx_runtime.jsx("option", { value: "moderate", children:
|
|
592
|
-
react_jsx_runtime.jsx("option", { value: "strict", children:
|
|
627
|
+
react_jsx_runtime.jsx("option", { value: "off", children: t.safeSearchOff }, "off"),
|
|
628
|
+
react_jsx_runtime.jsx("option", { value: "moderate", children: t.safeSearchModerate }, "moderate"),
|
|
629
|
+
react_jsx_runtime.jsx("option", { value: "strict", children: t.safeSearchStrict }, "strict"),
|
|
593
630
|
],
|
|
594
631
|
}),
|
|
595
632
|
react_jsx_runtime.jsx("p", {
|
|
596
633
|
className: "dshfs-hint",
|
|
597
|
-
children:
|
|
634
|
+
children: t.safeSearchHint,
|
|
635
|
+
}),
|
|
636
|
+
],
|
|
637
|
+
}),
|
|
638
|
+
react_jsx_runtime.jsx("div", {
|
|
639
|
+
className: "dshfs-field",
|
|
640
|
+
children: [
|
|
641
|
+
react_jsx_runtime.jsx("div", {
|
|
642
|
+
className: "dshfs-label",
|
|
643
|
+
children: t.bingMarketLabel,
|
|
644
|
+
}),
|
|
645
|
+
react_jsx_runtime.jsx("select", {
|
|
646
|
+
className: "dshfs-select",
|
|
647
|
+
value: bingMarket,
|
|
648
|
+
style: { colorScheme: selectColorScheme },
|
|
649
|
+
disabled: !ready || saving,
|
|
650
|
+
onChange: (e) => setBingMarket(e.target.value),
|
|
651
|
+
children: [
|
|
652
|
+
react_jsx_runtime.jsx("option", { value: "zh-CN", children: t.marketZhCN }, "zh-CN"),
|
|
653
|
+
react_jsx_runtime.jsx("option", { value: "zh-TW", children: t.marketZhTW }, "zh-TW"),
|
|
654
|
+
react_jsx_runtime.jsx("option", { value: "en-US", children: t.marketEnUS }, "en-US"),
|
|
655
|
+
react_jsx_runtime.jsx("option", { value: "en-GB", children: t.marketEnGB }, "en-GB"),
|
|
656
|
+
react_jsx_runtime.jsx("option", { value: "ru-RU", children: t.marketRuRU }, "ru-RU"),
|
|
657
|
+
react_jsx_runtime.jsx("option", { value: "ja-JP", children: t.marketJaJP }, "ja-JP"),
|
|
658
|
+
react_jsx_runtime.jsx("option", { value: "de-DE", children: t.marketDeDE }, "de-DE"),
|
|
659
|
+
react_jsx_runtime.jsx("option", { value: "fr-FR", children: t.marketFrFR }, "fr-FR"),
|
|
660
|
+
react_jsx_runtime.jsx("option", { value: "es-ES", children: t.marketEsES }, "es-ES"),
|
|
661
|
+
react_jsx_runtime.jsx("option", { value: "ko-KR", children: t.marketKoKR }, "ko-KR"),
|
|
662
|
+
],
|
|
663
|
+
}),
|
|
664
|
+
react_jsx_runtime.jsx("p", {
|
|
665
|
+
className: "dshfs-hint",
|
|
666
|
+
children: t.bingMarketHint,
|
|
598
667
|
}),
|
|
599
668
|
],
|
|
600
669
|
}),
|
package/lib/index.js
CHANGED
|
@@ -15,13 +15,40 @@ const USER_AGENT =
|
|
|
15
15
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36";
|
|
16
16
|
const ACCEPT_LANG = "zh-CN,zh;q=0.9,en;q=0.8";
|
|
17
17
|
|
|
18
|
+
// 语言 → Bing 本地化档案:{ market, acceptLang }。
|
|
19
|
+
// lang 字段(设置页可切换)驱动 Bing 的 mkt + Accept-Language,让非中文用户
|
|
20
|
+
// 也能拿到本地化结果(俄语搜俄文等)。bingMarket 显式设置时优先于映射。
|
|
21
|
+
const LANG_PROFILES = {
|
|
22
|
+
zh: { market: "zh-CN", acceptLang: "zh-CN,zh;q=0.9,en;q=0.8" },
|
|
23
|
+
en: { market: "en-US", acceptLang: "en-US,en;q=0.9" },
|
|
24
|
+
ru: { market: "ru-RU", acceptLang: "ru-RU,ru;q=0.9,en;q=0.8" },
|
|
25
|
+
ja: { market: "ja-JP", acceptLang: "ja-JP,ja;q=0.9,en;q=0.8" },
|
|
26
|
+
de: { market: "de-DE", acceptLang: "de-DE,de;q=0.9,en;q=0.8" },
|
|
27
|
+
fr: { market: "fr-FR", acceptLang: "fr-FR,fr;q=0.9,en;q=0.8" },
|
|
28
|
+
es: { market: "es-ES", acceptLang: "es-ES,es;q=0.9,en;q=0.8" },
|
|
29
|
+
ko: { market: "ko-KR", acceptLang: "ko-KR,ko;q=0.9,en;q=0.8" },
|
|
30
|
+
};
|
|
31
|
+
// market → 语言(bingMarket 显式设置时反推 accept-language,避免中文优先 header 污染)
|
|
32
|
+
const MARKET_TO_LANG = {
|
|
33
|
+
"zh-CN": "zh-CN,zh;q=0.9,en;q=0.8",
|
|
34
|
+
"zh-TW": "zh-TW,zh;q=0.9,en;q=0.8",
|
|
35
|
+
"en-US": "en-US,en;q=0.9",
|
|
36
|
+
"en-GB": "en-GB,en;q=0.9",
|
|
37
|
+
"ru-RU": "ru-RU,ru;q=0.9,en;q=0.8",
|
|
38
|
+
"ja-JP": "ja-JP,ja;q=0.9,en;q=0.8",
|
|
39
|
+
"de-DE": "de-DE,de;q=0.9,en;q=0.8",
|
|
40
|
+
"fr-FR": "fr-FR,fr;q=0.9,en;q=0.8",
|
|
41
|
+
"es-ES": "es-ES,es;q=0.9,en;q=0.8",
|
|
42
|
+
"ko-KR": "ko-KR,ko;q=0.9,en;q=0.8",
|
|
43
|
+
};
|
|
44
|
+
|
|
18
45
|
const FREE_SEARCH_NS = "free-search";
|
|
19
46
|
const BRIDGE_PREFIX = "/api/dsh-free-search-settings";
|
|
20
47
|
const FREE_ENGINES = ["ddg", "ddg-lite", "bing", "searxng", "anysearch"];
|
|
21
48
|
const ALL_ENGINES = ["ddg", "ddg-lite", "bing", "searxng", "anysearch", "exa", "tavily", "keenable", "perplexity", "deepseek-official"];
|
|
22
49
|
|
|
23
50
|
// 当前插件版本(发布时与 package.json 同步)
|
|
24
|
-
const PLUGIN_VERSION = "0.4.
|
|
51
|
+
const PLUGIN_VERSION = "0.4.23";
|
|
25
52
|
// 检查更新的 npm registry 元数据地址(dsh-free-search 是 npmjs 上的公开包)
|
|
26
53
|
const NPM_REGISTRY_URL = "https://registry.npmjs.org/dsh-free-search/latest";
|
|
27
54
|
const PLUGIN_NPM_URL = "https://www.npmjs.com/package/dsh-free-search";
|
|
@@ -192,7 +219,7 @@ function uniqueSources(sources, limit) {
|
|
|
192
219
|
return out;
|
|
193
220
|
}
|
|
194
221
|
|
|
195
|
-
async function fetchHtml(url, signal) {
|
|
222
|
+
async function fetchHtml(url, signal, acceptLang) {
|
|
196
223
|
// 单次请求超时 12s,避免挂起被当成 Connection error
|
|
197
224
|
let response;
|
|
198
225
|
try {
|
|
@@ -201,7 +228,7 @@ async function fetchHtml(url, signal) {
|
|
|
201
228
|
const onAbort = () => controller.abort();
|
|
202
229
|
signal?.addEventListener("abort", onAbort);
|
|
203
230
|
response = await fetch(url, {
|
|
204
|
-
headers: { "user-agent": USER_AGENT, "accept-language": ACCEPT_LANG },
|
|
231
|
+
headers: { "user-agent": USER_AGENT, "accept-language": acceptLang ?? ACCEPT_LANG },
|
|
205
232
|
signal: controller.signal,
|
|
206
233
|
redirect: "follow",
|
|
207
234
|
});
|
|
@@ -223,11 +250,11 @@ async function fetchHtml(url, signal) {
|
|
|
223
250
|
}
|
|
224
251
|
|
|
225
252
|
// 带重试的抓取:网络错误/空结果时重试,间隔 1.5s,最多 3 次
|
|
226
|
-
async function fetchHtmlWithRetry(url, signal) {
|
|
253
|
+
async function fetchHtmlWithRetry(url, signal, acceptLang) {
|
|
227
254
|
let lastError;
|
|
228
255
|
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
229
256
|
try {
|
|
230
|
-
const html = await fetchHtml(url, signal);
|
|
257
|
+
const html = await fetchHtml(url, signal, acceptLang);
|
|
231
258
|
if (html.length > 500) return html;
|
|
232
259
|
lastError = new Error(`empty response (${html.length} bytes)`);
|
|
233
260
|
} catch (error) {
|
|
@@ -300,12 +327,19 @@ async function searchDdgLite(query, maxResults, options, signal) {
|
|
|
300
327
|
}
|
|
301
328
|
|
|
302
329
|
async function searchBing(query, maxResults, options, signal) {
|
|
303
|
-
|
|
330
|
+
// mkt:显式 bingMarket 优先;否则按 lang 映射(zh→zh-CN, ru→ru-RU ...)
|
|
331
|
+
const profile = LANG_PROFILES[options?.lang] ?? LANG_PROFILES.zh;
|
|
332
|
+
const market = options?.bingMarket ?? profile.market;
|
|
333
|
+
const params = new URLSearchParams({ q: query, mkt: market });
|
|
334
|
+
// Accept-Language:显式 bingMarket 时按 market 反推(避免中文 header 污染),否则用 lang 档案
|
|
335
|
+
const acceptLang = options?.bingMarket
|
|
336
|
+
? (MARKET_TO_LANG[market] ?? ACCEPT_LANG)
|
|
337
|
+
: (profile.acceptLang ?? ACCEPT_LANG);
|
|
304
338
|
const adlt = options?.safeSearch ?? "off";
|
|
305
339
|
if (adlt === "off") params.set("adlt", "off");
|
|
306
340
|
else if (adlt === "moderate") params.set("adlt", "moderate");
|
|
307
341
|
else if (adlt === "strict") params.set("adlt", "strict");
|
|
308
|
-
const html = await fetchHtmlWithRetry(`${BING_URL}?${params}`, signal);
|
|
342
|
+
const html = await fetchHtmlWithRetry(`${BING_URL}?${params}`, signal, acceptLang);
|
|
309
343
|
const blocks = html.match(/<li class="b_algo"[\s\S]*?<\/li>/g) ?? [];
|
|
310
344
|
const sources = [];
|
|
311
345
|
for (const block of blocks) {
|
|
@@ -2024,6 +2058,7 @@ function apply(ctx, config) {
|
|
|
2024
2058
|
"You have the web_search tool. Its backend engine is chosen in Settings > Plugins > Free Search.",
|
|
2025
2059
|
"Current engine: " + (current().provider ?? "bing"),
|
|
2026
2060
|
"Safe search filter (Settings > Plugins > Free Search): " + (current().safeSearch ?? "off") + " (off|moderate|strict). Engine default off; applies to bing/ddg/ddg-lite.",
|
|
2061
|
+
"Bing market: " + (current().bingMarket ?? "zh-CN") + " (mkt + Accept-Language; e.g. ru-RU returns Russian results for Cyrillic queries).",
|
|
2027
2062
|
"",
|
|
2028
2063
|
"Available engines and their requirements:",
|
|
2029
2064
|
"- ddg (DuckDuckGo HTML) - FREE, no key (may be rate-limited)",
|
package/package.json
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-free-search",
|
|
3
|
+
"version": "0.4.23",
|
|
4
|
+
"description": "Free web search for DeepSeek Harness: 10 engines (Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable keyless) + time filtering + platform search + web_fetch, with web settings UI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./lib/index.js",
|
|
9
|
+
"./client": "./lib/client.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"lib/index.js",
|
|
14
|
+
"lib/client.js",
|
|
15
|
+
"cordis.patch.yml"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"deepseek-harness",
|
|
19
|
+
"dsh",
|
|
20
|
+
"dsh-plugin",
|
|
21
|
+
"web-search",
|
|
22
|
+
"duckduckgo",
|
|
23
|
+
"bing",
|
|
24
|
+
"tavily",
|
|
25
|
+
"exa",
|
|
26
|
+
"keenable",
|
|
27
|
+
"perplexity",
|
|
28
|
+
"search",
|
|
29
|
+
"free"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/DDDMUC/dsh-free-search.git"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=20"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@deepseek-ai/schemastery": "^3.18.1"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@deepseek-ai/dsh-settings": ">=0.1.0-rc.6",
|
|
47
|
+
"@deepseek-ai/dsh-tools": ">=0.1.0-rc.6"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@deepseek-ai/dsh-settings": "0.1.0-rc.7",
|
|
51
|
+
"@deepseek-ai/dsh-tools": "0.1.0-rc.7"
|
|
52
|
+
},
|
|
53
|
+
"dsh": {
|
|
54
|
+
"bundle": {
|
|
55
|
+
"patch": "cordis.patch.yml"
|
|
56
|
+
},
|
|
57
|
+
"client": {
|
|
58
|
+
"inject": [
|
|
59
|
+
"@deepseek-ai/dsh-client-runtime"
|
|
60
|
+
],
|
|
61
|
+
"platform": "web"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"dsh": ">=0.1.1-rc.1"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|