gausszhou/dsh-web-search-local ↗★ 0

@gausszhou/dsh-web-search-local

Keyless multi-engine web search + page fetch providers for the dsh web seam (no DeepSeek dependency). 适合想用本地多引擎搜索替代内置提供商的用户;需配置引擎与代理,部分引擎无代理会跳过。

Package
@gausszhou/dsh-web-search-local
Compatibility
Unverified
Harness peer range
^0.1.0-rc.8
Version
0.2.1
License
MIT
Last updated
Aug 20, 2026

Install

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:gausszhou/dsh-web-search-local

Configuration

config:
  engines: [searxng, google, duckduckgo, mojeek, bing, baidu, sogou, 360]  # member list (execution is layered: searxng → global → cn, parallel within a layer)
  skipWithoutProxy: [google, duckduckgo, mojeek] # engines NOT attempted when no proxy is available ([] = always attempt)
  searxngBaseUrl: 'http://127.0.0.1:8080'   # optional; runs first when set
  proxyUrl: ''                              # '' auto | 'off' | 'http://host:port'
  searchTimeoutMs: 12000
  fetchTimeoutMs: 20000
  maxFetchBytes: 1048576
  maxSources: 12
  cacheTtlMs: 300000                        # in-memory result cache
  engineMinIntervalMs: 1500                 # min gap between engine calls (anti rate-limit)
  engineCooldownMs: 600000                  # skip engine after captcha/anomaly/verification-wall (0 = off)
  engineRetryCooldownMs: 60000              # skip engine after generic failure (0 = off)
  userAgent: '
'

The default engine list executes in three layers, in order, with same-layer engines queried in parallel and merged:

  1. searxng — a private SearXNG instance (when searxngBaseUrl is set) is already a meta-search aggregation, so its results win immediately and lower layers are skipped
  2. global — Google, DuckDuckGo, Mojeek (need a proxy in CN; with no proxy they are skipped outright, see skipWithoutProxy)
  3. cn — Bing, Baidu, Sogou, 360 (reachable directly with no VPN/proxy required)

A layer with no results (empty, blocked, or skipped engines) degrades to the next, so the global engines never break the directly reachable cn engines. The google engine is scrape-fragile (consent wall, sorry/ bot detection, JS-required enablejs wall); for reliable Google results prefer a SearXNG instance with the google engine enabled. On open networks where the global engines work directly, set skipWithoutProxy: [].

A private SearXNG instance (Docker: docker run -p 8080:8080 searxng/searxng) is the most robust engine of all: meta-search aggregation, a JSON API, no per-engine scraping.

Configuration & settings integration

The plugin declares a schemastery Config schema (one field per entry of defaultConfig()) and registers a settings namespace (web-search-local) through dsh's settings service — the same mechanism the built-in web-search-deepseek, shell, and agent-loop plugins use. This gives you:

  • Config is validated and normalized, and can be persisted through dsh's settings service.
  • Each provider operation reads the live config section: a value changed through the settings UI takes effect on the next search/fetch with no reload. (Config and SETTINGS_NAMESPACE are also named exports.)
  • On a profile with no settings service, behavior is byte-for-byte the same as before: the composition config passed to apply(ctx, config) from cordis.patch.yml still wins.

The visible card in the "Plugin configuration" panel is a client-side React component — the built-in cards (Terminal / Agent loop / Web search) are hand-written inside the bundled dsh-client-ui-settings-plugins client package. For this external plugin to gain an editable card in that panel it must additionally ship a ./client half that registers a settings.plugin.item card. So "the configuration UI" for this plugin = the server-side schema integration above plus a client card.