dsh-tavily-search
A Tavily-backed web search provider plugin for the
DeepSeek Harness (dsh). It routes the harness
web-search seam through the Tavily API and ships a GUI configuration card
in Settings → Plugins where you can toggle the provider on/off and store your
Tavily API key.
Everything is a plugin: this package composes a Cordis host plugin (the search provider) and a web client bundle (the settings card).
Features
- Registers a web-search provider with id
tavilyand points the harness web seam at it via the bundle patch (cordis.patch.yml). - GUI configuration card (
设置→插件) named tavily-search with:- an on/off switch — when off, the provider reports itself unavailable and refuses to search;
- an API key field written through the harness credentials service (never stored in the settings file or echoed back to the client).
- API key resolution order:
- a literal
apiKeyconfigured in theweb-search-tavilysettings section; - the harness credentials service, under the credential reference named by
apiKeyEnv(defaultTAVILY_API_KEY); - the launching environment (
TAVILY_API_KEY).
- a literal
- Configurable Tavily endpoint via
baseURL(defaulthttps://api.tavily.com).
Requirements
- A DeepSeek Harness (
dsh) installation where the web search seam is composed. - A Tavily API key from https://app.tavily.com.
Installation
A dsh plugin is an npm package that composes into a profile via the profile's
dsh.profile.bundles layer stack — there is no separate "plugin directory" to
drop folders into. Everything this package needs is declared in its own
dependencies (pinned to exact versions, see package.json), so a single
install into a profile is sufficient.
Target a profile whose web-search seam is already composed — the default web
profile (bundles @deepseek-ai/dsh-base + @deepseek-ai/dsh-web-app) is the
usual one.
From a source checkout:
git clone https://github.com/libinghui55/dsh-tavily-search.git
cd dsh-tavily-search
npm ci
Then add the package to a profile with the dsh CLI:
dsh plugin --profile web add <path-to-dsh-tavily-search>
(<path-to-dsh-tavily-search> can be an absolute path, link:..., a git spec,
or an npm registry name if you publish it.)
What dsh plugin does:
- Initializes the profile on first use.
- Runs
pnpm add <spec>inside the profile directory, installing the package (and its exact pinned dependencies) into the profile'snode_modules. - Reconciles the profile's
dsh.profile.bundleslayer stack against the installed state: any installed dependency whose manifest declaresdsh.bundle— this one does — is appended as a profile layer in dependency order, and a laterdsh plugin --profile web remove dsh-tavily-searchdrops it back out.
Because this package declares dsh.bundle.patch: ./cordis.patch.yml, joining
the layer stack pulls in the bundled patch, which:
- sets
web.searchProvider = tavilyso the web seam searches through Tavily; - inserts a
web-search-tavilyhost-plugin row whose config pointsapiKeyEnvatTAVILY_API_KEY.
Manual alternative (no dsh CLI)
Add the package to the target profile's package.json by hand and run
pnpm install there:
{
"dependencies": { "dsh-tavily-search": "0.1.0" },
"dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-tavily-search"] } }
}
pnpm install in the profile materializes it, and the harness applies
cordis.patch.yml because the package is listed in dsh.profile.bundles.
Provide your API key
Choose one of these:
A. GUI (recommended) — open 设置 → 插件, expand tavily-search, and
enter your key in the API key field, then Save. The key is written
through the harness credentials service (e.g. ~/.dsh/.credentials.yaml).
B. Credentials file — add a line to your credentials store:
TAVILY_API_KEY: tvly-xxxxxxxx
C. Environment — export TAVILY_API_KEY in the launching environment.
Note on environment shadowing: if
TAVILY_API_KEYexists in the process environment, the credentials service reports it as inherited (writable: false), so the GUI card disables its key field — an env-provided value cannot be overwritten from the UI. Store the key in the file (option A or B) rather than the environment if you want to edit it from the card.
Configuration
The plugin owns a settings namespace web-search-tavily with the schema:
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Master switch; false makes the provider unavailable. |
apiKey |
secret | — | Literal API key (written via credentials). |
apiKeyEnv |
string | TAVILY_API_KEY |
Credential reference resolved when no literal key is set. |
baseURL |
string | https://api.tavily.com |
Tavily endpoint override. |
Example .yml config:
# dsh.config / bundle patch
web-search-tavily:
enabled: true
apiKeyEnv: TAVILY_API_KEY
Bundle contents
index.js— host-side web search provider (TavilySearchProvider) and theweb-search-tavilysettings section.client.js— web client bundle: the plugin configuration card (settings.plugin.itemslot, keyed on theweb-search-tavilynamespace).cordis.patch.yml— bundles the provider into the web seam and resolves the API key reference.
Development
Run the offline smoke test from the profile that has the plugin installed (it
imports the profile-installed copy so @deepseek-ai/* deps resolve). The
smoke script is a local-only, gitignored helper; point it at the profile where
the package is installed:
node <profile>/node_modules/dsh-tavily-search/smoke.mjs
The test verifies: provider id tavily, availability, a real Tavily search,
and that enabled: false makes the provider unavailable and refuse to search.
Because the web client is served from its own bundle, changes to client.js
require a harness restart to be reloaded by dsh-client-modules.
License
MIT
No comments yet. Be the first to write one.