npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xfcodeai/dsh-web

v0.1.5-rc.5

Published

Abstract web access capability seam (ctx.web) for the DeepSeek Harness — search/fetch provider registry, registration-order-independent selection, request/result vocabulary, and the WebError taxonomy

Readme


description: "web 访问服务(ctx.web):部署方与插件作者如何通过可互换的提供方搜索 web 与抓取 URL,以及统一的选择策略与错误词汇。" kind: "package-reference"

@xfcodeai/dsh-web

English | 中文

概述

使用 dsh-web 搜索 web 或抓取 URL,而无需让调用方依赖特定厂商。它为每项操作选择可用后端,并为调用方提供一致的取消、错误和结果上限。在调用 ctx.web.search() 或 ctx.web.fetch() 的插件或工具中选择它;已交付的 dsh-tool-web 工具会为你加载它。搜索或抓取需要已配置且可用的提供方,因为本包自身不发起网络请求。

目录


使用本包

需要 web 访问的组合会加载 dsh-web 服务并挂载至少一个后端——搜索提供方和/或抓取提供方——插件或工具作者随后直接调用 ctx.web.search() 与 ctx.web.fetch()。服务会为每次调用解析后端,因此除非调用方配置了提供方 id,否则它们看不到提供方 id。

何时选择

当插件或工具必须搜索或抓取、又不希望硬编码厂商时选择本服务;只使用已交付的 web_search/web_fetch 工具的组合会通过 dsh-tool-web 自动加载本服务。当组合从不访问 web 时,你不需要它。服务本身不增加任何网络访问能力:没有至少一个可用提供方时,每次调用都会以结构化 WebError 失败。

最小配置

加载服务并让唯一挂载的后端自动选择,或用 searchProvider/fetchProvider 固定提供方 id。环境变量 $DSH_WEB_SEARCH_PROVIDER 与 $DSH_WEB_FETCH_PROVIDER 提供相同字段,不是另一条优先级链。

- name: '@xfcodeai/dsh-web'
- name: '@xfcodeai/dsh-web-search-exa'
- name: '@xfcodeai/dsh-web-fetch-http'

| 字段 | 默认值 | 含义 | |---|---|---| | searchProvider | (未设置) | 固定的搜索提供方 id;未设置时仅在恰好一个可用时自动选择 | | searchProviderOrder | (未设置) | 未固定 id 时的独占搜索允许列表;不可用的 id 会被跳过,不会选中未列出的提供方(例如 deepseek-official) | | fetchProvider | (未设置) | 固定的抓取提供方 id;未设置时仅在恰好一个可用时自动选择 |

生成的配置目录是每个受支持字段及其 JSDoc 的穷尽式真源。

搜索与抓取

search() 执行一次查询,返回可选的提供方答案与可引用的来源列表;服务强制执行 request.maxResults:截断 sources[] 并设置 truncated。fetch() 获取一个 URL,返回其最终 URL、状态码、解码后的正文与截断标志;非 2xx 响应是结果,不是错误。

// Search the web; sources[] is capped to maxResults:
const result = await ctx.web.search({ query: 'deepseek harness', maxResults: 8 })

// Fetch one URL; a non-2xx response is a result, not an error:
const page = await ctx.web.fetch({ url: 'https://example.com' })

两个调用都接受可选的 AbortSignal,用于把取消转发给提供方。规范化的请求与结果形状是调用方赖以构建的约定;web 子系统 参考中的词汇章节对其有穷尽式描述。

提供方选择

每次调用都在执行时解析提供方,注册或加载顺序从不影响结果。已配置的提供方 id 在已注册且可用时优先;没有配置 id 时,服务运行唯一可用的提供方,或在情况不明时明确失败:

| 情况 | 结果 | |---|---| | 已配置 id 已注册且可用 | 运行该提供方 | | 已配置 id 未注册 | WEB_PROVIDER_CONFIGURED_MISSING | | 已配置 id 已注册但不可用 | WEB_PROVIDER_CONFIGURED_UNAVAILABLE | | 无 id,顺序中第一个可用提供方 | 运行该提供方 | | 无 id,已设置顺序且其中没有可用提供方 | WEB_PROVIDER_UNAVAILABLE | | 无 id,未设置顺序,恰好一个已注册的可用提供方 | 运行它 | | 无 id,没有可用提供方 | WEB_PROVIDER_UNAVAILABLE | | 无 id,未设置顺序,多个可用提供方 | WEB_PROVIDER_AMBIGUOUS |

提供方的可用性是一项廉价的局部检查——例如其 API 密钥是否存在——并且从不发起网络调用,因此选择保持快速且确定。

失败与恢复

失败抛出 WebError,携带稳定、可按机器路由的 code;消息补充细节,例如缺失的提供方 id 或歧义候选集合。调用方按 code 路由并决定如何降级。要改变一次调用使用的后端,请重新配置固定的 id、挂载或卸载提供方,或修正提供方配置使其可用性检查通过。


理解实现

本节解释服务背后的设计决策;可观察行为已在使用本包中完整说明。

设计理念

本包建立在一个刻意的分离之上:

  • 一个 seam,两个独立操作。 搜索与抓取没有共享请求 schema 或业务逻辑,但它们共用一个服务,使提供方选择、取消、错误与产品配置只有一个归属方。并行的 Search/Fetch 方法对是有意为之。
  • 选择绝不依赖顺序。 能力要么固定提供方 id,要么在恰好注册一个可用提供方时自动选择;search()/fetch() 在执行时解析提供方。
  • 服务拥有结果上限。 maxResults 由 seam 在提供方返回后强制执行,因此超量返回的提供方绝不可能泄漏超出调用方要求的来源。

源码地图

| 文件 | 职责 | |---|---| | src/index.ts | 插件入口:WebRuntime 服务、两个提供方注册表与执行时选择 | | src/types.ts | 词汇:请求/结果类型、封闭的 WebFetchBody 联合与 WebError 分类体系 | | — | 不发布运行时不变式配套项;提供方映射是私有数据,服务会在每次调用时执行提供方选择并强制执行结果上限;该 seam 不发布独立注册表,也不发布请求/结果观测流。 |

数据模型

请求与结果类型定义了调用方赖以构建的规范化词汇——Search 请求/结果对与 Fetch 请求/结果对各一组——穷尽式字段与 JSDoc 见 src/types.ts 与 web 子系统 参考。两个刻意的选择塑造了它们:WebFetchBody 是这里拥有的封闭联合(html | text),因此新增类型会破坏编译,直到每个消费方都处理它;WebError 继承 HarnessError,携带开放的字符串 code,因此消费方必须容忍提供方专有的取值。来源字段保持可选,因为并非每个提供方都返回全部字段。

选择流程

执行时,服务先按配置 id、再按唯一可用提供方解析提供方,没有明确赢家时抛出对应的 WebError。搜索结果随后经过 capSources:把 sources[] 截断到 maxResults 并标记 truncated。注册基于 effect:提供方随调用 fiber 注册,fiber 释放时注销;同一能力类型下重复的 id 会在注册时被拒绝。


进一步探索

当包级约定不够用时阅读以下页面。它们从共享词汇逐步进入已交付后端、面向模型的工具与设计依据。


模型体验

间接地,通过 dsh-tool-web:该工具把 seam 规范化的搜索结果与抓取正文渲染给模型,而本服务不贡献任何提示词或 schema。

KV Cache 影响

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

已知限制与延期工作

这些限制说明本服务单独使用时在哪些方面不完整。它们是当前包约束。

  • 没有观测接口:没有提供方变更事件或能力状态查询;可用性只能通过执行搜索或抓取并按抛出的 code 路由来观测,无提供方失败是通用的 WEB_PROVIDER_UNAVAILABLE,不枚举逐提供方原因(见 Agent Note)。
  • 搜索请求只携带 query 与 maxResults:提供方无关的控制项(新近程度、域名过滤条件、区域提示、搜索深度)暂缓至后端都能诚实支持时(见 seam Agent Note)。
  • WebFetchBody 没有 pdf 分支:可提取文本的 PDF 支持属于明确的延期工作;封闭联合会使新增该分支成为跨 web 包、由编译强制执行的变更。
  • 提供方支持的页面提取不属于 fetch() 范围:Firecrawl/Tavily 风格的 web_extract 能力延期,而不会扩展抓取操作。

开发备注

本开发备注是维护者的工作上下文:开放问题与尚未决定的探索方向。它明确不具权威性——已交付的行为、限制与既定理由以上文和相关 Agent Note 为准。

未来:观测提供方状态

没有提供方变更事件或能力状态查询;消费方只能通过执行调用并按抛出的 code 路由来观测可用性。如果消费方需要逐提供方原因,恢复一个小的观测接口是可行的,但已归档的简化笔记记录了为何放弃此前的那个接口。