- Startseite
- Plugins
- Modelle & Anbieter
- dsh-web-tavily
dsh-web-tavily
vvilliam-qwq/dsh-web-tavily
Tavily-backed search provider for dsh: registers the `tavily` provider on ctx.web so the web_search tool runs against the Tavily Search API
Installation
dsh plugin --profile web add github:vvilliam-qwq/dsh-web-tavilyREADME
dsh-web-tavily
English · 中文
Built for dsh-TUI.
A host-plane Cordis plugin for dsh: it registers the tavily search provider
on dsh's web seam (ctx.web), so the web_search tool goes to the Tavily
Search API (POST https://api.tavily.com/search).
- It does not replace the
web_searchtool itself: the tool, its system prompt and its result card are untouched — only the search backend changes. - DeepSeek's native search (
web-search-deepseek) stays available as a fallback you can switch to; setweb.searchProviderback todeepseek-official(or delete the key) to do so. - The key is resolved per operation in this order: a literal
apiKeyin the configuration first, then the credentials service (refs:in~/.dsh/.credentials.yaml), then the launch environment. The reference defaults toTAVILY_API_KEY, and the provider never stores a key.
How it works
- The provider (id
tavily) registers onctx.web;web.searchProvider: tavilymakes it the default choice. - When
web_searchruns, the seam hands{ query, maxResults }to this provider. - The provider resolves the key (a snapshot per operation, so one search never
mixes two configuration versions) and calls
{baseURL}/search. - The response is mapped:
results[] → sources[](title/url/content→snippet, pluspublished_date → publishedAtwhen present), and a top-levelanswer(Tavily's AI summary) becomes the tool's optionalcontent. - Cancellation (signal) →
WEB_ABORTED; an HTTP failure or an unparsable body →WEB_PROVIDER_ERROR; a missing key →WEB_PROVIDER_CREDENTIAL_MISSING(the message names the configuration step).
Defaults
| Field | Default | Meaning |
|---|---|---|
apiKeyEnv | TAVILY_API_KEY | Credential reference (environment-variable name). |
apiKey | (none) | A literal key, only when you do not want a reference. |
baseURL | https://api.tavily.com | Overridable with TAVILY_BASE_URL. |
searchDepth | basic | basic / advanced (deeper, higher credit use). |
topic | general | general / news. |
includeAnswer | true | Ask for Tavily's AI summary (mapped to content). |
maxResults | 10 | Fallback cap; web_search passes 8 per call, Tavily's ceiling is 20. |
Install
-
Get a Tavily account and an API key. Register at https://tavily.com/, create a key in the dashboard, and store it under
refs:in~/.dsh/.credentials.yaml— or exportTAVILY_API_KEYin the environment that launches dsh (see Where the key lives). Never commit the key to a repository or paste it into a settings document. -
Install it into your profile — it is published on npm as
dsh-web-tavily:dsh plugin --profile dsh-tui add dsh-web-tavily # from a local checkout instead: # dsh plugin --profile dsh-tui add file:<path to this package> -
Restart dsh-tui before editing the patch (
/restart). Adding a plugin only rewrites the profile's bundle list; it does not load the plugin into the running session. Restarting here means thetavilyprovider is already registered when the patch below is saved. -
Make tavily the default search backend. This has to be written in the profile's user patch layer (the
web:section ofsettings.yamldoes not affect service configuration) — edit~/.dsh/profiles/dsh-tui/cordis.patch.ymland add:- id: web name: '@deepseek-ai/dsh-web' config: searchProvider: tavily fetchProvider: http-trusted⚠️ Saving this file hot-reloads the running session — it is not "restart to apply". The profile's patch layer is watched, so the session is reconfigured the instant the file is written. If the plugin is not loaded yet (step 3 skipped), the
webrow immediately points at a provider that is not registered, andweb_search/ web fetch fail in that session withWEB_PROVIDER_CONFIGURED_MISSING. A/restartrecovers it, because at boot the plugin is registered and the patched row is read together. Editing the patch first and restarting later is also safe for the boot — it just leaves this session's web capability unavailable until that restart.The
webrow belongs to thedsh-baselayer, so do not add a new row withinsert:— the duplicate id crashes the boot withduplicate loader entry id: web. Override the existing row by id instead, and note that an override replaces the whole config, which is whyfetchProvideris restated above.
Configuration
The plugin's own section lives in ~/.dsh/settings.yaml (it also appears in the
settings screen under “Web search Tavily”):
dsh-web-tavily:
apiKeyEnv: TAVILY_API_KEY
searchDepth: basic
topic: general
includeAnswer: true
maxResults: 10
TAVILY_BASE_URL overrides the API origin; the credential reference defaults to
TAVILY_API_KEY.
The settings screen renders this namespace as a bilingual card (Web search (Tavily) / 联网搜索(Tavily)) with a description for every field, so the reference is the one control you normally touch. The key itself never enters the settings document.
Where the key lives (local only — never in a repository)
Add it under refs: in ~/.dsh/.credentials.yaml (that file holds machine-local
credentials; do not commit or share it):
refs:
TAVILY_API_KEY: 'tvly-...'
Exporting TAVILY_API_KEY in the environment that launches dsh works too — the
credentials store is consulted first, the launch environment second. A literal
key in dsh-web-tavily.apiKey is accepted as well and wins over both, but it
puts the secret in a settings document, so treat it as a last resort.
Switching back to DeepSeek's native search
Set web.searchProvider to deepseek-official (or delete the key and let the
seam use the only provider available). The seam does not fall back
automatically: a broken Tavily configuration fails loudly rather than quietly
using DeepSeek.
Proxy-compatible fetch (http-trusted)
The plugin also registers an http-trusted fetch provider, which works around
web_fetch being refused by the official http provider's safety preflight in
fake-IP proxy environments (Clash and friends resolving domains to
198.18.0.0/15): WEB_BLOCKED_URL: resolves to a non-public IP address.
- It reuses the official
@deepseek-ai/dsh-web-fetch-httptransport and relaxes exactly one check — the “resolved address must be public” preflight additionally allows198.18.0.0/15, the proxy fake-IP range. Everything else is unchanged: private, loopback and reserved ranges are still refused (WEB_BLOCKED_URL), IPv6 answers are still dropped, and address pinning, same-origin redirects, the content-type allowlist, byte/character caps and the no-credentials cookie rule all stay in place. - ⚠️ Security boundary: SSRF protection moves from “enforced inside the host”
to “trust the local proxy's DNS decision”, so the last word on reachability
belongs to the proxy's routing rules. Intended for a single-user machine with
a trusted self-hosted proxy; for shared or public deployments go back to the
official
httpprovider (below). - Addresses that are special by construction (
http://192.168.x.x/and friends) are still refused.
# the web row in ~/.dsh/profiles/dsh-tui/cordis.patch.yml
config:
searchProvider: tavily
fetchProvider: http-trusted
Rolling back to the official http: set fetchProvider back to http. The
cost is that web_fetch is refused again in a fake-IP proxy environment, in
exchange for the complete safety preflight.
Troubleshooting
duplicate loader entry id: webon boot — the profile'scordis.patch.ymlusedinsert:for a row that already exists; rewrite it as the by-id override shown above.web_searchanswersWEB_PROVIDER_CONFIGURED_MISSING— thewebrow points at a provider that is not registered: either the plugin did not load (check the bundles list), orcordis.patch.ymlwas saved before the plugin was loaded, which is a live reload (see Install)./restartrecovers it.web_fetchanswersWEB_BLOCKED_URL ... non-public IP— the proxy fake-IP preflight refused it: switch tohttp-trusted, or turn the proxy's fake-IP mode off.
Limitations
- A missing or invalid Tavily key makes
web_searchfail (WEB_PROVIDER_CREDENTIAL_MISSING/WEB_PROVIDER_ERROR); the message names what to configure. max_resultsis clamped to Tavily's ceiling of 20.- An invalid
searchDepth/topicis an error, never a silent fallback to the default.
Publishing
- Repository: https://github.com/VviLliAm-qwq/dsh-web-tavily (public)
- Release:
v*tags drive.github/workflows/release.yml, which publishes to npm through trusted publishing (OIDC) — no token is stored in the repository.
Usage
Once installed and configured, let the model call web_search as usual: the
sources list it returns (and the optional summary) now comes from Tavily.
License
MIT — see LICENSE.
Ähnliche Plugins
dsh-routing-suite
yjh051108/dsh-routing-suite
dsh-plugin-subscriptions
v1ki/dsh-plugin-subscriptions
dsh-commandcode-provider
mars-sea/dsh-commandcode-provider
dsh-workbuddy-connect
corrinehu/dsh-workbuddy-connect