全部插件

DSH / BUNDLE / CLIENT-UI

@junjiangao/dsh-web-search-tavily

v0.2.0junjiangao / dsh-web-search-tavily5f4587dc25

可安装组合包UI 与客户端插件社区 · Topic 自动分析Web UI

概览

@junjiangao/dsh-web-search-tavily

Tavily-backed search provider for the DeepSeek Harness web capability seam (ctx.web): keyless mode, full official search parameters, settings section, and credentials support

README / ZH

插件文档

@junjiangao/dsh-web-search-tavily

English | 中文

Tavily 支持的 WebSearchProvider,用于 DeepSeek Harness 的 web 能力 seamctx.web),实现参考 packages/web/web-search-* 家族。它向 ctx.web 注册提供方——不拥有 ctx.web,也不注册面向模型的工具(后者属于 @deepseek-ai/dsh-tool-web)。

亮点:

  • Keyless 模式——config、设置、凭据、环境变量均无 key 时,请求进入 Tavily keyless 模式:不带 Authorization、携带 x-tavily-access-mode: keyless、client-source 为 dsh-web-search-tavily-keyless
  • 官方搜索参数全量——深度、主题、时间范围、日期、天数、结果数、include/exclude 域名、answer、raw content、图片、favicon、用量、自动参数、精确匹配、语言、国家、每源 chunk 数均可配置。
  • 设置界面 + 凭据——dsh-settings 设置段(web 设置页可编辑)+ dsh-credentials 密钥解析;key 也可来自字面量 apiKey 或环境变量。
  • 标准 bundle——声明 dsh.bundle,支持 dsh plugin add 安装。

安装

本包以 GitHub 仓库形式分发(暂不发布 npm)。用 dsh plugin 安装到 profile(内部转发 pnpm):

# GitHub spec——main 分支
dsh plugin --profile <name> add github:junjiangao/dsh-web-search-tavily

# 需要可复现性时可 pin commit(后续推送不会改变安装内容)
# dsh plugin --profile <name> add github:junjiangao/dsh-web-search-tavily#<sha>

# 或本地目录
dsh plugin --profile <name> add /path/to/dsh-web-search-tavily

# 或打包 tarball(无需构建授权)
pnpm pack
dsh plugin --profile <name> add ./dsh-web-search-tavily-0.1.0.tgz

构建产物 lib/ 已提交进仓库,且包内不声明任何生命周期脚本,因此 git 安装无需构建授权——pnpm 不会要求 allowBuilds。开发时请用 pnpm build 重新构建,并把更新后的 lib/ 与源码改动一起提交。(不含 lib/ 的纯源码版本才需要 allowBuilds 步骤;建议直接用上面的 main 分支流程。)

指定 tavily 为 search provider

注册提供方 ≠ 启用提供方。web seam 按 id 选择:

  • web 插件行的 searchProvider,或
  • DSH_WEB_SEARCH_PROVIDER(仅当 web 行未设置 searchProvider 时生效——dsh-base 目前固定 searchProvider: deepseek-official,所以只设环境变量无效)。

多个搜索插件并存时,在 profile 的 cordis.patch.yml(晚于所有 bundle 层)固定 tavily:

- id: web
  config:
    searchProvider: tavily   # web 行若还有其他键,必须一并重述

本 bundle 只 insert 自己的插件行,刻意不覆盖 web 行:patch 行是整行替换 config(不做深合并),多个 provider bundle 不应争抢该行。

配置

除标注 schema 默认值的字段外均可选。同一 schema 即设置界面字段。

配置键 默认值 含义
apiKey (无) Tavily API 密钥字面量。优先用 apiKeyEnv/凭据服务,避免密钥进配置文件;存入设置的字面量在设置描述中会被脱敏。
apiKeyEnv TAVILY_API_KEY 携带密钥的凭据引用/环境变量名。
baseURL https://api.tavily.com 端点基址;追加 /search。支持 TAVILY_BASE_URL 环境变量回退。
searchDepth basic ultra-fast
topic (无) general
timeRange (无) day
startDate / endDate (无) 绝对日期(YYYY-MM-DD),发送为 start_date / end_date
days (无) 天数窗口,发送为 days。正整数。
maxResults (无) 请求未带 maxResults 时的默认结果数;钳制到 Tavily 上限 20。
includeDomains / excludeDomains [] 域名列表,发送为 include_domains / exclude_domains;空列表不发送。
includeAnswer false true
includeRawContent false true
includeImages false 发送为 include_images;seam 暂不展示图片结果(暂缓)。
includeImageDescriptions false 发送为 include_image_descriptions
includeFavicon false 发送为 include_favicon;暂不展示(暂缓)。
includeUsage false 发送为 include_usage;暂不展示(暂缓)。
autoParameters false 发送为 auto_parameters
exactMatch false 发送为 exact_match
language (无) 发送为 language
filterByLanguage false 发送为 filter_by_language
country (无) 发送为 country
chunksPerSource (无) 发送为 chunks_per_source。正整数。

密钥解析顺序:字面量 apiKeydsh-credentialsapiKeyEnv 引用)→ 环境变量(apiKeyEnv,默认 TAVILY_API_KEY)→ keyless

# 有 key(环境变量)
- id: web-search-tavily
  name: '@junjiangao/dsh-web-search-tavily'
  config:
    apiKeyEnv: TAVILY_API_KEY

# 有 key(字面量——优先凭据服务/环境变量)
- id: web-search-tavily
  name: '@junjiangao/dsh-web-search-tavily'
  config:
    apiKey: !!js process.env.TAVILY_API_KEY

# Keyless——任何来源都无 key 时自动降级
- id: web-search-tavily
  name: '@junjiangao/dsh-web-search-tavily'

Keyless 模式

所有 key 来源为空时,请求不带 Authorization、携带 x-tavily-access-mode: keyless、client-source 为 dsh-web-search-tavily-keyless——与官方 SDK 约定一致。keyless 是合法状态而非配置错误。Tavily 服务端会对 keyless 限流,并可能忽略或降级部分参数(结果数、深度、answer)。keyless 仅支持 search(和 extract);本插件只调用 /search

设置界面与凭据

WEB_SEARCH_TAVILY_SETTINGS_NAMESPACE = 'web-search-tavily'(普通命名空间常量)通过 dsh 0.1.2 设置服务把配置注册为设置段(settings.installSection,由 ctx.inject(['settings'], ...) 门控):web 设置页可编辑上表全部字段,修改后下一次搜索即生效,无需重注册。推荐把 key 存入凭据服务(web Models/设置页写入),引用名为 apiKeyEnv。设置文档中存字面量 apiKey 虽被支持但会落盘——优先凭据服务或环境变量。

客户端设置卡片

包内还携带一个 client 面(dsh.client 声明 + exports["./client"],构建产物 lib/client.js):向 web 设置页的"插件 → 插件配置"页注册 web-search-tavily 卡片,可编辑常用字段(API key、key 环境变量、接口地址、结果数量、检索深度、topic、answer/images/raw content/favicon/usage 开关)。卡片绑定同一个 settings namespace;其他字段保存即写入设置文档,API key 走凭据域,不落设置文档。调用面按部署版本逐次探测:dsh 0.1.1-rc.xconnection.api.credentials(对象参数、{ result: { ok, value | error } } 信封,与该版本官方卡片完全一致),dsh 0.1.2+remote.credentials(位置参数、RemoteResult 信封);读取失败会退避重试直到调用面就绪。@deepseek-ai/dsh-client-ui-primitives 已声明为 bundle 外部依赖(取原生 chevron 图标)。安装后需重启 web 服务让 client 模块图收录该包(client-modules 启动时扫描 loader 条目)。

卡片特性:

  • 原生卡片外观:披露头部、正文与页脚逐条对齐官方 PluginCard——原生 primitives 14px chevron 图标、官方间距/字号/配色(tavily- 前缀样式表)、文档只读时的只读提示,以及宿主确认保存后的自动折叠。默认收起,整行头部(标题+描述+chevron)点击展开;未保存改动时头部显示徽标。
  • 推荐配置:"使用推荐配置"填入 Tavily 官方默认值apiKeyEnv: TAVILY_API_KEYsearchDepth: basicmaxResults: 5includeAnswer/includeImages/includeRawContent/includeFavicon/includeUsage: false)——刻意不用激进值,因为 keyless 模式(无 key)会限流并可能忽略/降级结果数、深度、answer 参数,官方默认在有无 key 两种模式下行为一致。填入后为暂存状态,可逐个调整再保存。
  • 密钥状态自动识别:与官方 web-search-deepseek 卡片一致,卡片通过 credentials.describe 询问凭据域——TAVILY_API_KEY 环境变量已导出、或凭据库/设置字面量中已有 key 时直接显示"已配置",无须手动设置;只有所有来源都为空时才显示 keyless 提示条(说明限流与参数降级风险)。由启动环境提供的 key 在此处只读:密钥输入框随之禁用(与官方卡片同样依据 writable 判定);写入被真正拒绝时,卡片逐字显示宿主的拒绝信息,而不是笼统的保存失败文案。
  • 字段说明:每个字段带 hint,标注 tokens 影响(includeRawContent 显著增加 tokens/成本、includeAnswer 增加输出 tokens、maxResults 越多越耗、searchDepth: advanced 更慢更耗)。

映射

  • answer(启用 includeAnswer 时)→ content
  • 每条结果 → WebSearchSourceurltitlepublishedAtpublished_datesnippet 优先 content、空时回退 raw_content。空字段省略;无 URL 的结果丢弃。
  • max_results 钳制到 20(Tavily 文档上限);最终 maxResults 截断仍由 seam 执行(truncated)。

模型体验

dsh-tool-web 间接影响:模型看到经 maxResults 限制的 URL、标题、snippet、发布日期,以及启用 includeAnswer 时的生成答案。提供方失败以 WebError WEB_PROVIDER_ERROR 呈现(消息取 Tavily 错误体,含 keyless 限流信封);取消以 WEB_ABORTED 呈现。携带凭据的请求在接触 Location 目标前拒绝重定向。

KV Cache 影响

不会直接导致 KV Cache 失效;请求前缀变更由上述消费方负责。

开发

pnpm install
pnpm build        # tsc → lib/;lib/ 需随源码改动一起提交
pnpm test         # vitest 单元测试
pnpm test:coverage  # src 逐文件 100% 门禁
pnpm test:e2e     # 真实 API smoke;无 $TAVILY_API_KEY 时自跳过

与 harness 仓库内包(继承 tsconfig.base.json、产出 lib/types + 打包的 lib/index.js)不同,本独立仓库用单次 tsc 产出 lib/,公开 API 不变。若要放入 deepseek-harness/packages/web/web-search-tavily,把 peer/dev 依赖改为 workspace:^ 并按 harness 布局调整 tsconfig。

已知限制与暂缓事项

  • 仅实现 search——未实现 Tavily extract/crawl/map/research;keyless 本来也只允许 search/extract。
  • keyless 受服务端限流,参数可能被降级;插件不做本地假设。
  • includeImages / includeImageDescriptions / includeFavicon / includeUsage 会透传请求,但 seam 暂无图片/用量/favicon 展示面。
  • 选择归用户所有:安装本 bundle 只注册提供方;固定 searchProvider: tavily 是 profile 层的决定(见上文)。
  • 中止按 signal 分类:fetch 中止或已中止的 signal 映射为 WEB_ABORTED

许可证

MIT

LIMITATIONS

已知限制

- **仅实现 `search`**——未实现 Tavily `extract`/crawl/map/research;keyless 本来也只允许 search/extract。 - **keyless 受服务端限流**,参数可能被降级;插件不做本地假设。 - **`includeImages` / `includeImageDescriptions` / `includeFavicon` / `includeUsage`** 会透传请求,但 seam 暂无图片/用量/favicon 展示面。 - **选择归用户所有**:安装本 bundle 只注册提供方;固定 `searchProvider: tavily` 是 profile 层的决定(见上文)。 - **中止按 signal 分类**:fetch 中止或已中止的 signal 映射为 `WEB_ABORTED`。