설치
pnpm add dsh-web-search-ddg이 명령은 GitHub 저장소 주소에서 생성됩니다. 실행 전에 업스트림 README와 소스를 검토하고 재현성이 필요하면 release 또는 commit을 고정하세요.
README
유지 관리자가 작성한 문서 스냅샷입니다.
dsh-web-search-ddg
中文 | English
Zero-token DuckDuckGo search provider for the DeepSeek Harness (DSH) web capability seam (ctx.web).
DSH's shipped search route (deepseek-official) performs every web_search as a full billed model round trip on deepseek-v4-flash — even when your session model is something else entirely. This plugin replaces that with your local browser: it drives Chrome/Edge/Chromium headless against DuckDuckGo's HTML endpoint and parses the result links out of the dumped DOM.
- Zero model tokens per search — no API key, no auxiliary model request
- Zero dependencies — Node builtins only; no Playwright/Puppeteer download
- Keeps the shipped provider registered — switching is a one-line config change, not an uninstall
Requirements
- A DSH host (≥
0.1.0-rc) providing thectx.webseam - A local Chromium-family browser. Detected automatically on macOS (Chrome, Edge, Chromium) and Linux (
/usr/bin/chromium,/usr/bin/google-chrome); override withchromePath - Node.js ≥ 18
Install
In your DSH profile directory (e.g. ~/.dsh/profiles/web), install the package as an out-of-tree plugin:
pnpm add dsh-web-search-ddg
Then edit the profile's cordis.patch.yml to mount it and make it the default search provider. Note that a patch row replaces the target row's whole config (no deep merge), so the web row must restate every key — the shipped row owns only searchProvider:
# Select this provider for the model-facing web_search tool.
- id: web
config:
searchProvider: ddg-browser
# Mount the plugin (registers provider id `ddg-browser`).
- insert:
- id: web-search-ddg
name: dsh-web-search-ddg
The shipped web-search-deepseek row stays untouched: its provider remains registered and available, so switching back is one line (searchProvider: deepseek-official). DSH's selection is a single explicit id, not a priority chain — there is no silent fallback by design.
Verify the composed tree without starting the host:
dsh --profile web --dump-config | grep -A2 searchProvider
Restart the host to apply (host-side plugin rows do not hot-reload).
Configuration
All keys optional; the row config goes to the insert entry above.
| Key | Default | Meaning |
|---|---|---|
chromePath | first detected browser | Absolute path to a Chromium-family executable. |
timeoutMs | 20000 | Per-attempt budget. On timeout, buffered DOM output still counts as success (Chrome's --dump-dom process often lingers after printing). Two attempts run per search; keep 2 × timeoutMs under tool-web's searchTimeoutMs (DSH ships 60s). |
virtualTimeBudgetMs | 8000 | Chrome's --virtual-time-budget — how long the page may settle before the DOM is dumped. |
Behavior notes
- Latency is ~10–20s per search. The DOM dump is usually ready quickly, but the child process frequently fails to exit on its own (background services never quiesce), so results often land at the timeout guard. The guard reads the buffered output, so the search still succeeds — just not fast.
- DuckDuckGo anomaly pages fail loudly. When the endpoint serves its anti-bot challenge, the plugin surfaces an explicit error naming the cause and the fallback (
switch searchProvider back to deepseek-official). It never silently degrades. - The headless UA is overridden with a plain desktop Chrome UA — the endpoint keys on the
HeadlessChromemarker and blocks it otherwise. If searches start failing everywhere, DuckDuckGo may have tightened detection; bump the UA string inindex.js. - Every attempt runs in a throwaway
--user-data-dirunder the OS temp dir, cleaned up best-effort after the process dies (a leaked temp dir never fails a search).
How it works
spawnthe browser with--headless --dump-dom --virtual-time-budgetand the UA override againsthttps://html.duckduckgo.com/html/?q=<query>- Read the serialized DOM from stdout; a kill guard bounds hung pages, and buffered output at timeout is accepted
- Parse
<a class="result__a">(titles) and<a class="result__snippet">(snippets); both hrefs are//duckduckgo.com/l/?uddg=<encoded>redirects, so decode the real target URL fromuddgand pair title/snippet on it - Return
{ sources: [{ url, title?, snippet? }], truncated: false }through the seam — the model-facingweb_searchtool and result cards work unchanged
Development
npm test # end-to-end: registers on a stub ctx.web and runs one real search
CHROME_PATH=/path/to/browser npm test
TEST_QUERY="something else" npm test
License
프로젝트 파일 및 신호
표시된 항목은 디렉터리 스냅샷에서 감지된 공개 저장소 신호입니다.
저장소 정보
- 언어
- JavaScript
- 라이선스
- MIT
- 마지막 업데이트
- 2026. 8. 16. 오후 2:19
신중하게 설치하기
소스 코드, 권한, 수명 주기 스크립트, 의존성 및 네트워크 접근을 검토하고 신뢰하지 않는 플러그인은 격리 환경에서 테스트하세요.