Introduction¶
DeepSeek Harness (DSH) uses a plugin-based architecture. When building agents or applications that need internet connectivity, a common requirement is to integrate with the Tavily API for search and to fetch web page content. This plugin aims to provide DSH with a capability layer. It registers two model-visible tools, solves the problem of tools becoming unavailable when a single account’s quota is exhausted, and provides shell-seam-based web scraping capability.
Core Capabilities¶
The plugin registers two model-visible tools and mounts itself as the sole fetch provider for the host web registry.
tavily_search: A search tool based on the Tavily API. It returns JSON data containing a source list (URL, title, summary, publication time). The plugin implements a multi-API-key polling pool; when a single account’s quota is exhausted, it automatically switches to the next key, preventing the entire tool from failing.web_fetch: A tool that fetches a single page by invokingcurlthrough a shell seam. It does not depend on the Tavily API and requires no key. It returns the HTTP status code and the body content after removing tags.
To distinguish it from the built-in DeepSeek provider, the search function is not registered as a web.search() provider. Instead, it exists as a model-visible tool, avoiding selection ambiguity.
Installation and Activation¶
This plugin is a profile bundle. After installing it once, all sessions under that profile can use the tools described above.
dsh plugin --profile web add @arcaneorion/dsh-tavily-web
After installation, DSH must be restarted (dsh --profile web), because host plugins do not support hot reload. The startup log should contain information similar to (key pool: N ref(s), cooldown 900s) to confirm successful loading.
Configuration¶
By default, the plugin configures a polling pool containing 8 key reference names (TAVILY_API_KEY through TAVILY_API_KEY_8). Unconfigured reference names are automatically skipped and can be run at no cost.
To override the default configuration, modify the user-level ~/.dsh/profiles/<profile>/cordis.patch.yml file, rather than the patch included with the package:
- id: tavily-web
config:
keyRefs: [TAVILY_API_KEY, TAVILY_WORK_KEY] # 替换默认家族
apiKeys: [] # 字面量 key,排在 keyRefs 之后;密钥更该放 seam
cooldownSeconds: 900 # 403/429/432 后的退避秒数
Technical Details and Notes¶
Compatibility¶
The current plugin targets DSH 0.2.0-rc.1 (peer declaration is 0.2.0). Before upgrading the DSH version, it is recommended to first verify the peer dependency version, because the contracts for the web registry and shell seam may change across versions.
Distribution Format Limitations¶
The npm tarball contains only src/, cordis.patch.yml, and README.md; it does not include the tests/ directory. To run tests, a repository copy is required.
Entry File Type¶
The main field in package.json must point to a regular .js file (src/tavily-web.js) and cannot point to a .ts file. This is because ESM in node_modules does not support stripping types, and loading a .ts file directly causes a silent failure (the loader cannot initialize).
Curl Invocation Pitfall¶
Error bodies from the Tavily API (such as 432 errors) are valid JSON, but curl still returns exit code 0 when encountering HTTP errors. If code only parses JSON without checking HTTP status codes, API errors may be misinterpreted as “empty search results.” This plugin enforces status code checking in web_fetch.
Conclusion¶
This plugin provides DSH with stable multi-key Tavily search and web scraping capabilities, making it suitable for scenarios that require highly available internet functionality. For more source code, test cases, and directory information, see the GitHub repository.