DSH Plugins Marketplace

DSH Plugins

Plugins

/

Tools & Capabilities

/

dsh-web-search-searxng

s

dsh-web-search-searxng

Identified★ 1

Internet search via SearXNG for the DeepSeek Harness: the plugin launches its own container and provides the agent with web_search without any vendor keys. · SearXNG-backed web search for the DeepSeek Harness, with its own container and no vendor key.

dsh-web-search-searxng

ci Русский | English

Бандл для DeepSeek Harness, который даёт агенту работающий web_search без ключа вендора. Он подключает провайдера поиска на базе SearXNG к шву веб-доступа харнесса (ctx.web) и по умолчанию поднимает собственный контейнер SearXNG — то есть установка бандла и есть вся настройка.

Принцип работы и отличие от «голого» SearXNG

«Голый» подход — это адаптер на тридцать строк: взять {base}/search?format=json и вернуть results[]. Он исходит из того, что SearXNG у вас уже поднят, JSON в нём включён, порт свободен, образ свежий, а контейнер жив. И он не отличает «ничего не нашлось» от «движки внутри отказали»: в обоих случаях приходит HTTP 200 с пустым списком.

Наш плагин встраивает в пакет сам инстанс и надёжность:

  1. Установка = рабочий инстанс. Плагин тянет searxng/searxng, берёт первый свободный порт, генерирует settings.yml (JSON включён, лимитер выключен, секрет создаётся один раз), ждёт /healthz и останавливает контейнер при выгрузке. Отдельного шага «сначала подними SearXNG» нет; если инстанс уже есть — один параметр baseURL, и контейнер не создаётся.
  2. Отказ движков — это ошибка, а не пустой ответ. SearXNG отдаёт unresponsive_engines; плагин делает второй проход (по fallbackEngines или без сужающих фильтров) и только потом сообщает, какие движки отказали.
  3. Временные сбои переживаются. Сеть, таймаут попытки, 429/5xx повторяются; отмена вызывающим — никогда; худшая задержка (retries + 1) × timeoutMs.
  4. Повторный запрос ничего не стоит. TTL-кэш на 60 секунд: агент часто повторяет один и тот же поиск, второй раз ответ приходит из памяти.
  5. Результат пригоден для цитирования. Только http(s), сниппет ≤ 800 символов, publishedAt, ответ движка (answers) как content — без придуманного текста.

Движки — это источники, которые SearXNG опрашивает параллельно. В сгенерированных настройках стоит use_default_settings: true, поэтому включён набор по умолчанию текущей версии: в категории general это brave, duckduckgo, google cse, wikipedia и wikidata (плюс вспомогательные вроде currency, dictzone и lingva); google, bing, qwant и yandex в конфиге присутствуют, но выключены — им нужны ключи или они нестабильны, и включаются они в settings.yml. Полный список включённых движков своего инстанса:

curl -s http://127.0.0.1:8888/config | jq -r '.engines[] | select(.enabled) | .name'

Чего мы не делаем: не зовём внешний API, не требуем ключей, не платим за поиск и не сочиняем сводок — content приходит от движка. Провайдер регистрируется как searxng, инструмент web_search остаётся штатным; пакет — обычный ESM без зависимостей и сборки.

Требования

ТребованиеЗачем
Демон Docker, доступный пользователю, который запускает dsh (docker version)плагин сам запускает и останавливает контейнер
~400 МБ диска и сеть при первом запускеоднократная загрузка образа
Node 22+ (харнесс и так его требует)fetch, AbortSignal.timeout
DSH с швом ctx.web (текущие 0.2.x)провайдер регистрируется в этот шов; на старых сборках ряд просто ждёт сервис и ничего не делает
pnpm и git, доступные команде dshdsh plugin ставит пакет через pnpm, спецификация github: требует git

Нет Docker? Укажите baseURL на существующий инстанс SearXNG — тогда ничего не запускается (см. Использовать существующий инстанс).

Установка

Пакет объявляет dsh.bundle, поэтому установка одновременно и активирует его:

# из GitHub (поддерживаемый способ)
dsh plugin --profile web add github:svoemesto/dsh-web-search-searxng

# из локальной копии (для разработки)
dsh plugin --profile web add /path/to/dsh-web-search-searxng

Внутри уже запущенного харнесса то же самое делает plugin_manager → install_bundle с каталогом пакета в качестве target. После этого спросите агента о чём-нибудь актуальном: web_search отвечает через ваш инстанс.

Первый запуск медленный — один раз. Плагин загружает образ, создаёт контейнер и ждёт /healthz (до startupTimeoutMs, по умолчанию 90 с). Пока инстанс не готов, поиск завершается ошибкой «SearXNG instance is not ready: …»; загрузка при этом продолжается в фоне, и следующий поиск уже проходит.

Что создаётся

ЧтоГде
Контейнерdsh-searxng (имя настраивается), --restart unless-stopped, публикация только на 127.0.0.1:<свободный порт>:8080
Настройки$DSH_HOME/searxng/settings.yml (по умолчанию ~/.dsh/searxng/), пишутся один раз и никогда не перезаписываются
Секретгенерируется в эти настройки; сохраняется между перезапусками и обновлениями
Портпервый свободный порт начиная с port (8888), просматривается до 50 портов — машина, где SearXNG уже занят, продолжает работать

Контейнер запускается при активации плагина и останавливается при его выгрузке (завершение харнесса, HMR-перезагрузка, удаление плагина). Сам контейнер сохраняется, поэтому следующий старт занимает секунды; данные и секрет остаются в $DSH_HOME/searxng.

Что меняется в вашем профиле

Две строки патча, обе видны в dsh --profile <имя> --dump-config:

  • ряд web-search-searxng — сам провайдер (по умолчанию port: 8888);
  • переопределение ряда web: searchProvider: searxng и fetchProvider: http. Патч заменяет config целиком, поэтому fetchProvider указан явно — иначе после установки у web_fetch не осталось бы провайдера. Если в профиле уже сохранён оверрайд из Settings → Plugins → Web search, он сильнее патча: поиск останется за DeepSeek, хотя плагин установлен.

Контейнер с именем dsh-searxng, созданный не этим плагином, не переиспользуется и не останавливается: плагин проверяет метку dsh.plugin=dsh-web-search-searxng, а в чужом случае отказывается работать с понятным сообщением (задайте другой containerName).

Настройка

Все поля необязательны, у всех есть рабочие значения по умолчанию.

ПолеПо умолчаниюСмысл
baseURL(не задано)Использовать этот существующий инстанс и ничего не запускать. Не задано → свой контейнер.
port8888Первый порт-кандидат для контейнера; занятые пропускаются.
imagesearxng/searxng:latestЛюбой совместимый образ SearXNG (зеркало, закреплённый тег).
containerNamedsh-searxngКонтейнер, которым владеет плагин.
dataDir$DSH_HOME/searxngКаталог на хосте с settings.yml.
instanceNameDSH web searchПодпись в собственном интерфейсе инстанса.
startupTimeoutMs90000Бюджет ожидания готовности (1000–600000).
timeoutMs20000Бюджет одного поиска.
language(не задано)Передаётся как language; не задано = значение инстанса.
categories(не задано)general, news, …
safesearch(не задано)0, 1, 2.
timeRange(не задано)day, week, month, year.
numResults(не задано)Обрезка только когда вызывающий не передал maxResults; реальную границу держит шов.
apiKey(не задано)Передаётся как preference[api_key] для инстансов за ключом.
retries1Дополнительные попытки после первой, если ошибка повторяемая (0–5).
retryDelayMs300Пауза между попытками.
fallbackEngines[]Движки, на которые сужается повторная попытка, например ["brave", "duckduckgo", "google cse"]; пусто — повтор идёт без language, categories, time_range.
cacheTtlMs60000Время жизни закэшированного результата; 0 отключает кэш.
cacheMaxEntries200Сколько поисков держать в кэше, прежде чем вытеснить самый старый.

Неверные значения останавливают активацию с сообщением, называющим поле — опечатка никогда не превращается в молча неработающий поиск.

Пример строки (в патче бандла или профиля):

- insert:
    - id: web-search-searxng
      name: dsh-web-search-searxng
      config:
        port: 8888
        language: ru

Использовать существующий инстанс

config:
  baseURL: http://127.0.0.1:8888

Тогда контейнер не создаётся и Docker не нужен. Полезно, когда на машине уже работает SearXNG для других задач или инстанс живёт на другом хосте.

Как отображаются результаты

  • results[] → {url, title?, snippet?, publishedAt?}; записи без абсолютного http(s)-URL отбрасываются, пустые сниппеты опускаются (не выдумываются), сниппеты ограничены 800 символами;
  • первый непустой ответ движка (answers[]) становится content — это реальный вывод движка, а не текст, сочинённый здесь;
  • нет результатов и непустой список unresponsive_engines → WEB_PROVIDER_ERROR с именами движков, чтобы «полусломанный» инстанс был виден, а не выглядел как честный пустой ответ.

Ошибки несут коды шва: WEB_PROVIDER_ERROR (HTTP-ошибка, неразбираемое тело, таймаут, сеть, неготовность) и WEB_ABORTED (отмена вызывающим).

Повторы и кэш

Попытка повторяется, когда сбой временный: сетевая ошибка, таймаут попытки, HTTP 429/5xx или — случай, которому научил поиск текстов в Караоке — HTTP 200 с нулём результатов и непустым списком unresponsive_engines. Повтор — это не тот же самый запрос:

  • если задан fallbackEngines, поиск сужается до этих движков (engines=bing,brave,…), а фильтры сохраняются;
  • иначе запрос повторяется без language, categories, time_range — именно эти сужения способны обнулить в остальном отвечаемый запрос.

Худшая задержка — (retries + 1) × timeoutMs; с умолчаниями это 40 с, что укладывается в 60-секундный бюджет инструмента. Отмена вызывающим не повторяется.

Одинаковые поиски кэшируются в памяти процесса: ключ включает запрос, границу результатов, language, categories, safesearch, timeRange, список резервных движков и адрес инстанса. Запись живёт cacheTtlMs (по умолчанию 60 с), кэш держит cacheMaxEntries поисков. Он локальный для процесса — без файлов и без общего состояния между разными хостами Harness — и хранит только успехи, поэтому сбой не прячет более поздний удачный поиск.

Диагностика

СимптомПричина и что делать
docker is not available on this machineЗапустите Docker или задайте baseURL.
SearXNG instance is not ready: … did not become healthyСмотрите docker logs dsh-searxng; возможно, ещё идёт первая загрузка образа.
no free port in 8888..8937Уменьшите port или освободите порт; каждый контейнер занимает один.
Поиск даёт странные или скудные результатыSearXNG агрегирует сторонние движки; docker logs показывает, какие отказали (unresponsive_engines).
Два харнесса на одной машинеОни делят имя контейнера и порт; второй переиспользует запущенный. Для изоляции задайте разные containerName + port.
container "dsh-searxng" exists but was not created by this pluginНа машине уже есть контейнер с этим именем, но без нашей метки. Задайте другой containerName в конфиге или удалите тот контейнер.
УдалениеСнятие бандла останавливает контейнер; чтобы вернуть диск — docker rm -f dsh-searxng и удалить $DSH_HOME/searxng.

Безопасность

  • Контейнер публикуется только на 127.0.0.1; из локальной сети он недоступен.
  • JSON-вывод включён, а ограничитель частоты выключен — это безопасно только благодаря привязке к loopback. Если открываете инстанс наружу, включите ограничитель в settings.yml и поставьте его за прокси.
  • Секретный ключ генерируется локально и хранится только в settings.yml.

Разработка

Зависимостей и сборки нет: исходники и есть артефакт.

index.js              точка входа плагина (apply, жизненный цикл, выбор режима)
src/config.js         валидация и значения по умолчанию
src/container.js      жизненный цикл docker: inspect / start / pull+create / health / stop
src/settings.js       генерация settings.yml (+ одноразовый секрет)
src/provider.js       клиент JSON-API SearXNG и маппинг результатов
test/unit.test.mjs    юнит-набор (фейковый docker, без сети)
test/docker.smoke.mjs живой контейнер: ensure → search → stop → rm

Текст карточки плагина в DSH — по-русски: харнесс поставляет только локали zh/en, поэтому русский текст лежит в locale/en.json (и в locale/ru.json), чтобы отображаться в интерфейсе; английская документация — в README.en.md.

node --test test/unit.test.mjs   # конфиг, настройки, жизненный цикл контейнера, маппинг, ошибки
node test/docker.smoke.mjs       # настоящий контейнер; нужны Docker и сеть, поднимает dsh-searxng-smoke

CI гоняет юнит-набор на Node 22 и 24 на каждый push (.github/workflows/ci.yml); проверка с контейнером — ручная (.github/workflows/docker-smoke.yml).

Релиз

Репозиторий и есть канал распространения: шага «публикация в реестр» нет.

  1. Поднимите version в package.json и добавьте запись в CHANGELOG.md.
  2. Закоммитьте, поставьте тег v<version> и запушьте тег.
  3. Создайте GitHub-релиз на этот тег (gh release create v<version> или через веб-интерфейс).

Ставят — и закрепляют версию — прямо из GitHub:

dsh plugin --profile web add github:svoemesto/dsh-web-search-searxng
dsh plugin --profile web add github:svoemesto/dsh-web-search-searxng#v2.0.1

Чтобы плагин находили в списках сообщества, публикуйте репозиторий с темой dsh-plugin на GitHub.

Лицензия

MIT — см. LICENSE.

Comments

Loading…

From the same category

reactive-resume

DeepSeek Harness plugin for Reactive Resume: bridges your resumes and job applications into a Harness session over MCP.

Tools & CapabilitiesManifest valid

★ 41.7k

↓ 94/wk

MIT

Aug 24, 2026

dsh plugin --profile web add dsh-plugin-reactive-resume

by Tencent

Let AI agents use your real, logged-in browser without interrupting your work. CLI + extension for browser automation across any shell-capable AI agent.

Tools & CapabilitiesManifest valid

★ 9.6k

↓ 8.9k/wk

MIT

TypeScript

Oct 25, 2026

dsh plugin --profile terminal add @wxg-prc-cpg/browser-skill-dsh-plugin

by dsh-market

The plugin market inside DeepSeek Harness — browse, search, one-click install · DSH 可视化插件市场

Tools & CapabilitiesManifest valid

★ 8.9k

↓ 175.2k/wk

MIT

TypeScript

Oct 24, 2026

dsh plugin --profile web add dshmarket

by yjh051108

dsh-routing-suite — injector + router-standard kit: install the runtime injector first, then the task-aware reasoning-mode router preset (measured P1-P23).

Tools & CapabilitiesManifest valid

★ 7k

MIT

JavaScript

Sep 18, 2026

dsh plugin --profile web add @dsh-external/dsh-super-injector

by Q00

Agent OS: the agent gets smarter on its own. We just hold the line: Interview-gated, staged evaluation, budgeted evolution loop. MCP server, 14 runtimes: Claude Code, Codex CLI, Gemini CLI, OpenCode,

Tools & CapabilitiesManifest valid

★ 6.3k

MIT

Python

Oct 25, 2026

Index only — not installable

by superdesigndev

OpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn

Tools & CapabilitiesManifest valid

★ 6.1k

NOASSERTION

Python

Oct 26, 2026

dsh plugin --profile web add treg-dsh