Bundle
@deepseek-ai/dsh-web-search-searxng
SearXNG-backed search provider (local meta-search JSON API) for the DeepSeek Harness web capability seam (ctx.web)
- Source
- acdcgz
- stars
- 5 stars
- License
- MIT
- Updated
- Updated 4 days ago
Readme
# @deepseek-ai/dsh-web-search-searxng
English | [中文](README.zh.md)
A [SearXNG](https://docs.searxng.org/)-backed `WebSearchProvider` for the DeepSeek Harness [web capability seam](https://github.com/deepseek-ai/deepseek-harness) (`ctx.web`). It calls a SearXNG instance's JSON API (`/search?format=json`) and maps the aggregated results into the seam's normalized `WebSearchResult`.
This is an **implementation** package: it registers a provider into `ctx.web`, resolves an optional API key through `ctx.credentials` or the process environment, records the auxiliary request in the initiating Agent session when one exists, and does not register a model-facing tool. It is a function/namespace plugin (`inject: ['web']`).
## Why SearXNG
- **Self-hosted & private**: your queries go to your own instance, not a third-party search vendor.
- **Zero per-search model cost**: unlike provider-backed search that issues a full model call, one search is a single HTTP GET — cheap and fast.
- **Multi-engine aggregation**: SearXNG merges Bing, Brave, Baidu, Google, DuckDuckGo, … behind one endpoint.
- **Portable**: point `baseURL` at any SearXNG — local Docker, a LAN instance, or a public one.
## Requirements
- A running SearXNG instance reachable from the DSH host (default `http://localhost:8080`).
- DeepSeek Harness profile with the `web` seam mounted (every standard profile ships it).
## Install
### One-command install (bundle)
The package ships a `dsh.bundle.patch` declaration (`cordis.patch.yml`), so a
single `dsh plugin add` registers the plugin **and** switches the web seam to
it — no YAML editing:
```bash
dsh plugin --profile web add /path/to/dsh-web-search-searxng
```
Configuration is environment-first — set these before launching `dsh` and no
config editing is required at all:
```bash
export SEARXNG_BASE_URL=http://localhost:8080 # optional; default http://localhost:8080
export SEARXNG_MAX_RESULTS=10 # optional; default 10
export SEARXNG_LANGUAGE=en # optional; 'all' (no param) by default
```
### Manual install (local development)
```bash
# 1. Make the package resolvable from the profile's node_modules
ln -sfn /path/to/dsh-web-search-searxng \
"$DSH_HOME/profiles/node_modules/@deepseek-ai/dsh-web-search-searxng"
# 2. Register the plugin and switch the search provider in cordis.patch.yml:
```
```yaml
- insert:
- id: web-search-searxng
name: '@deepseek-ai/dsh-web-search-searxng'
config:
baseURL: http://localhost:8080
maxResults: 10
- id: web
config:
searchProvider: searxng-local
```
Restart the DSH process (or the GUI) for the patch to take effect.
> Web profiles disable HMR reload by design; after editing `cordis.patch.yml` a process restart is required.
## Tests
```bash
node --test tests/provider.spec.js # 17 tests, zero dependencies (node:test)
```
## Config
| Key | Default | Meaning |
|---|---|---|
| `baseURL` | `http://localhost:8080` | SearXNG base URL; `/search` is appended. Falls back to `$SEARXNG_BASE_URL` from any environment layer. An unparseable value makes the provider unavailable. |
| `maxResults` | `10` | Upper bound on sources returned by one search (the seam also enforces its own bound). |
| `language` | `all` | Search language sent as `language=...` (e.g. `en`, `zh-CN`). `'all'` (or unset) omits the parameter entirely. Falls back to `$SEARXNG_LANGUAGE`. |
| `apiKey` | omitted | Literal SearXNG API key, when your instance requires one. Prefer `apiKeyEnv` so no secret enters configuration; a non-empty literal wins. |
| `apiKeyEnv` | `SEARXNG_API_KEY` | Credential reference resolved per search through `ctx.credentials`, or from the process environment when that seam is absent. A missing value is fine for keyless local instances. |
```yaml
- id: web-search-searxng
name: '@deepseek-ai/dsh-web-search-searxng'
config:
baseURL: http://localhost:8080
maxResults: 10
language: en
```
The entry above is the base layer of the `web-search-searxng` Settings section: a user layer over it reaches the NEXT search, because the provider projects the section per call rather than capturing it at registration. `apiKey` carries `role('secret')`, so it never rides a `describe()` response in any layer.
## Rate-limit note (local Docker behind Docker Desktop)
When SearXNG runs in Docker Desktop, requests from the host arrive with the compose **gateway IP** (e.g. `172.18.0.1`) as `REMOTE_ADDR`, not `127.0.0.1`. The SearXNG limiter would treat that as a foreign client and 429 the JSON API (`API_MAX = 4/hour`). This provider sends `X-Forwarded-For: 127.0.0.1` on every request; combined with `trusted_proxies = ['127.0.0.0/8']` and a `pass_ip` entry for the loopback and Docker bridge ranges in `limiter.toml`, the local client bypasses the JSON-API quota entirely.
If your SearXNG is remote (LAN/cloud), drop that header from the provider or adjust `trusted_proxies`/`pass_ip` on the server accordingly.
## Mapping
SearXNG returns no provider-generated answer content this provider trusts as `content`, so `content` is omitted. `sources[]` comes from `results[]`: `url` ← `url`, `title` ← `title`, `snippet` ← `content`, and `publishedAt` ← `publishedDate`. Results are deduplicated by URL.
Provider failures become `WEB_PROVIDER_ERROR`; caller cancellation becomes `WEB_ABORTED`. HTTP redirects are followed (SearXNG may 307 blob/redirect endpoints).
## Request logging
Immediately before dispatch, a search running under an initiating Agent appends the log-only `web/searxng-search-request` session event containing the resolved endpoint and query (secret-free). Direct programmatic provider calls outside an Agent have no initiating session to log.
## License
MIT
Install
dsh plugin --profile web add github:acdcgz/dsh-web-search-searxng
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install deepseek-ai-dsh-web-search-searxng from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.