DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Web Search Aggregation — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-web-search-aggregation

Web Search Aggregation

DeepSeek Harness 的聚合网络搜索提供商:通过 AnySearch / TinyFish / Tavily / Brave / Exa / Firecrawl / Jina / SerpApi / Serper 构建一个按优先级排列的队列,每个条目支持多个 API 密钥,并可针对每个请求按顺序回退。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-web-search-aggregation@0.1.10
README兼容性版本

兼容性与来源证明

Web Search Aggregation 以 dsh-web-search-aggregation 发布,当前版本为 0.1.10。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/20

版本

0.1.10stable
2026/8/24
0.1.9stable
2026/8/24
0.1.8stable
2026/8/23
查看其余 8 个版本收起版本
0.1.7stable
2026/8/23
0.1.6stable
2026/8/23
0.1.5stable
2026/8/23
0.1.4stable
2026/8/23
0.1.3stable
2026/8/23
0.1.2stable
2026/8/23
0.1.1stable
2026/8/23
0.1.0stable
2026/8/23

相关插件

正在加载相关插件…

最新版
0.1.10
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
503.2 kB
文件数
63
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 2
周下载
237
安全扫描
✓ v0.1.10 扫描通过
最近提交
2026/8/27
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 search-research 分类下经过校验的插件。

Browser Skill Dsh Plugin@wxg-prc-cpg/browser-skill-dsh-plugin向模型提供 BrowserSkill 浏览器自动化(browser_* 工具)的 DeepSeek Harness 工具插件Weknora@wxg-prc-cpg/dsh-weknora适用于 DeepSeek Harness (dsh) 的 WeKnora 知识检索工具:通过自有知识库进行语义搜索、文档阅读以及 RAG/代理回答。Free Searchdsh-free-searchDeepSeek Harness 的免费网页搜索:13 个引擎(Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl 无需密钥;Parallel/Perplexity/SerpBase/DeepSeek 需要密钥),支持时间筛选、平台搜索和 web_fetch,并提供网页设置界面。Find Plugindsh-find-plugin在代理中查找 DeepSeek Harness 插件——实时搜索 GitHub 上的 dsh-plugin 主题,并按星标数排序。

README

dsh-web-search-aggregation

中文 · npm · GitHub

An aggregated web-search provider for DeepSeek Harness (DSH): the built-in web_search tool is served through one prioritized queue over AnySearch / TinyFish / Tavily / Brave / Exa / Firecrawl / Jina / SerpApi / Serper — each provider can hold a pool of API keys that rotate per request, every failed attempt falls through to the next provider or key, and the first success wins.

Features

  • Prioritized queue, ordered fallback — entries are tried top-down per request; the first one that returns wins, and a failed entry falls through to the next. Order is edited live in the settings card; each provider kind can be queued at most once.
  • Multi-key pools with rotation — every provider reads exactly one credential (ANYSEARCH_API_KEY / TINYFISH_API_KEY / TAVILY_API_KEY / BRAVE_SEARCH_API_KEY / EXA_API_KEY / FIRECRAWL_API_KEY / JINA_API_KEY / SERPAPI_API_KEY / SERPER_API_KEY) whose value holds all of that provider's keys joined by ,. Within one entry the keys are tried in rotating order (round-robin per successful request), spreading load and quota across the pool.
  • Works out of the box — AnySearch allows anonymous access, so the queue answers searches before any key is configured. The shipped defaults simply enable all nine kinds — the order is whatever you arrange in the card; the key-required entries fall through until their credential is set.
  • Budget-aware — each attempt gets its own deadline (default 10 s, 1–60 s), so one hung upstream cannot eat the tool-level budget; five to six full fallbacks still fit inside 60 s.
  • Transparent failures — when every attempt fails, the error reports each one ([2] tavily/TAVILY_API_KEY#1: 401 unauthorized; …). An empty queue raises WEB_PROVIDER_UNAVAILABLE; caller cancellation raises WEB_ABORTED immediately.
  • Secret hygiene — key literals are never logged and never appear in failure records (which cite REF / REF#N labels only); the settings card shows keys as masked tags and never echoes stored values back.
  • Live configuration — the settings card (设置 → 插件 → 插件配置 → 聚合网页搜索 / Aggregated web search) edits the queue, keys, endpoints, and timeout; a committed change reaches the next search without a restart.

How it works

HalfLocationResponsibility
Host (server)src/Registers the search provider (id aggregated) into ctx.web; cordis.patch.yml pins the web seam's searchProvider to it and inserts the plugin row carrying the default queue.
Browser (client)src/client/Registers the Aggregated web search configuration card, which stages the queue and writes changes through the settings + credentials services.
web_search (tool-web)
   └─ ctx.web.searchProvider = aggregated
        ├─ queue (top-down, first success wins — order user-arranged):
        │     anysearch · firecrawl · tavily · tinyfish · brave · exa · jina · serpapi · serper
        │       │   keys = credential split on ','   ← pool per provider
        │       │   anonymous attempt allowed for key-less AnySearch
        │       └─ rotation cursor per entry (resets when the endpoint changes)
        ├─ per attempt: adapter request under its own deadline (default 10 s)
        └─ all failed → WEB_PROVIDER_ERROR with a per-attempt summary

Nine adapters ship today; another upstream is one adapter module plus one registry row.

KindAuthDefault endpointNotes
anysearchBearer, optionalhttps://api.anysearch.com/v1/searchanonymous access allowed; data.results[] envelope
tavilyBearerhttps://api.tavily.com/searchsends max_results; the generated answer rides content
tinyfishX-API-Keyhttps://api.search.tinyfish.aiGET ?query=…; no count control, the seam's maxResults truncates
braveX-Subscription-Tokenhttps://api.search.brave.com/res/v1/web/searchGET ?q=…&count=… (count clamped to 1–20, decorations off); page_age → publishedAt
exaBearerhttps://api.exa.ai/searchsends numResults (1–100) and contents.highlights; the first highlight is the snippet
firecrawlBearerhttps://api.firecrawl.dev/v2/searchsends limit (1–100); no scrapeOptions — plain results, no per-page scrape cost
jinaBearerhttps://s.jina.aiPOST / with {"q"}; X-Respond-With: no-content keeps it SERP-only (no per-page fetch); num (1–20) only when the request carries a count; description → snippet, publishedTime → publishedAt; EU mirror via https://eu.s.jina.ai
serpapiapi_key query paramhttps://serpapi.com/search.jsonGET ?engine=google&q=…&api_key=… — the key rides the URL because the API rejects it in headers/bodies; num (1–100) only when the request carries a count (num-bearing calls are documented as more CAPTCHA-prone); snippet → snippet, date → ; a body whose only payload is a top-level string — even at HTTP 200 — fails the attempt so the queue falls through

Requirements

  • DSH web profile (dsh web), Node.js ≥ 22.19 — the same floor as DSH itself (^22.19.0 || >=24). Source installs from GitHub run the prepare build, which needs the same range.
  • At least one reachable upstream: the default queue works with no credentials (AnySearch anonymous); Tavily / TinyFish / Brave / Exa / Firecrawl / Jina / SerpApi / Serper entries need their API keys to contribute.

Installation

From the npm registry (prebuilt — no build permission needed):

dsh plugin --profile web add dsh-web-search-aggregation

From a GitHub repository (source — pnpm runs the prepare build; allowlist the package in profiles/web/pnpm-workspace.yaml if pnpm blocks the build script):

dsh plugin --profile web add github:chendefine/dsh-web-search-aggregation

Or through the DSH plugin marketplace (设置 → DSH插件市场) — the repo carries the dsh-plugin topic and is indexed automatically.

After a bundle plugin is added to the profile layer stack, restart dsh web for it to load; uninstall with dsh plugin --profile web remove dsh-web-search-aggregation and restart again.

Configuration

The settings card (设置 → 插件 → 插件配置 → Aggregated web search) edits the web-search-aggregation settings section live:

plugin configuration card

FieldDefaultDescription
providersnine enabled entries — one per kindThe prioritized queue. Each entry: provider kind (each kind at most once), enabled toggle (a disabled entry stays configured but is skipped), and an optional endpoint base URL overriding the adapter's default. The shipped order carries no meaning; arrange it however you like.
attemptTimeoutMs10000Per-attempt deadline in ms (1000–60000). One attempt is cut off after this long and the queue moves to the next key or entry.

API keys are managed on each entry as masked tags: add one key at a time (+ or Enter), reorder by dragging tags off/on — tag order is the order a save writes and the runtime reads. Stored keys are never read back; a save replaces the whole pool, and closing every tag before saving clears the credential. Each provider's keys live in one fixed credential:

CredentialProviderRequiredValue format
ANYSEARCH_API_KEYAnySearchno — anonymous access worksone key bare, or several joined by ,
TAVILY_API_KEYTavilyyes, for the entry to servesame pool format
TINYFISH_API_KEYTinyFishyes, for the entry to servesame pool format
BRAVE_SEARCH_API_KEYBrave Searchyes, for the entry to servesame pool format
EXA_API_KEYExayes, for the entry to servesame pool format
FIRECRAWL_API_KEYFirecrawlyes, for the entry to servesame pool format
JINA_API_KEYJina Searchyes — the Search API rejects anonymous callssame pool format
SERPAPI_API_KEYSerpApiyes — the API rejects keyless callssame pool format (64-hex keys, no prefix)
SERPER_API_KEYSerperyes — the API rejects keyless calls (403)same pool format (keys carry no prefix)

Combining with other provider plugins

A bundle patch replaces the web seam row's whole config, so the layer applied last determines the final searchProvider / fetchProvider pair. This plugin's patch states only searchProvider: aggregated — it owns the search selection and nothing else. Two consequences:

  • With dsh-web-fetch-playwright installed before this plugin (or without it entirely), nothing needs adjusting: an unconfigured fetchProvider resolves to the single registered fetch provider automatically.

  • If another plugin's layer is applied after this one and resets searchProvider, pin the combined selection in your profile's own profiles/web/cordis.patch.yml — the user layer wins over every bundle layer:

    - id: web
      config:
        searchProvider: aggregated
        fetchProvider: playwright
    

Development

pnpm install
pnpm typecheck   # tsc --noEmit
pnpm test        # vitest run (103 unit tests, no network)
pnpm build       # tsc declarations + tsdown (host ESM + client module-registration bundle)

Repository layout:

src/
├── index.ts               # host entry: registers provider + settings section
├── config.ts              # schemastery schema, defaults, queue normalization
├── provider.ts            # AggregatedSearchProvider: queue walk, rotation, deadlines
├── keys.ts                # ','-joined key-pool vocabulary (parse/format/mask)
├── types.ts               # queue entry, config, per-attempt failure records
├── adapters/              # AnySearch / Tavily / TinyFish / Brave / Exa / Firecrawl / Jina / SerpApi / Serper adapters + shared HTTP
└── client/                # browser half: settings card, form model, locales
tests/                     # config, keys/adapters, provider, client-controller

See CONTRIBUTING.md for the development and release workflow, and SECURITY.md for the security model and reporting policy.

Security

Search queries and API keys leave the machine only toward the endpoints configured per queue entry (the nine providers' official APIs by default). Keys are stored in the DSH credentials domain — never in the settings file, never logged, never echoed back to the client. Failure records and logs cite masked references (TAVILY_API_KEY#2), not literals. No result data is retained beyond the session that requested it.

License

MIT © 2026 chendefine

publishedAt
error
serperX-API-KEY headerhttps://google.serper.dev/searchPOST {"q": …} with the key in the X-API-KEY header; num clamped into the API's documented 10–100 window and only sent when the request carries a count (below 10 clamps up — the seam truncates to maxResults); link → url, snippet → snippet, date (Google's displayed date) → publishedAt; non-2xx {"message": …} bodies (e.g. 403 keyless) surface their message