为 ctx.web 能力接缝提供匿名公共 HTTP(S) 资源获取实现,负责 URL 验证、HTTP 传输、重定向、超时、字节上限等安全资源检索
- 语言
- TypeScript
- License
- MIT
- 分支
- master
安装
$ dsh plugin --profile web add npm:@deepseek-ai/dsh-web-fetch-http在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
English | 中文
An anonymous public HTTP(S) WebFetchProvider for the harness web capability seam (ctx.web). It retrieves a concrete URL and returns a status code plus bounded decoded content.
This is an implementation package: it registers a provider into ctx.web, it does not own the key and it does not register a model-facing tool. It is a function/namespace plugin (inject: ['web']).
Responsibility split
The provider owns safe resource retrieval: URL validation, HTTP transport, redirect policy, a resource-backstop timeout, abort propagation, byte caps, charset decoding, content-type classification, and binary rejection. @deepseek-ai/dsh-tool-web owns presentation (HTML→markdown, truncation formatting). A non-2xx HTTP response is a result (status code + decoded body), not an error; WebError is reserved for failures to safely retrieve or represent the resource.
The provider's timeoutMs is a resource backstop for direct ctx.web.fetch() callers and misconfigured deployments, not the model-facing tool-call budget. dsh-tool-call-timeout-policy owns the web_fetch tool-call budget by arming exec.signal.
A shipping web-tool deployment sets the provider backstop above the tool budget, so model calls normally return TOOL_TIMEOUT. If the outer deadline reaches the provider first, the provider reports WEB_ABORTED and the outer policy replaces it with TOOL_TIMEOUT. WEB_FETCH_TIMEOUT therefore identifies a direct service caller whose provider budget elapsed.
Transport hygiene
- Accepts only
http:andhttps:URLs; rejects credentials in URLs (WEB_BLOCKED_URL) and over-long/malformed URLs (WEB_INVALID_URL). - Enforces a max URL length, response byte cap (
WEB_FETCH_TOO_LARGE), decoded body character cap, timeout (WEB_FETCH_TIMEOUT), and redirect hop cap. - Propagates the caller's abort signal (
WEB_ABORTED) into the network request and the streaming read. - Follows only same-origin redirects; a cross-origin redirect fails with
WEB_REDIRECT_BLOCKED, requiring a fresh tool call (the model of Claude Code's WebFetch). - Sends an explicit product
User-Agent, never a browser disguise. - Rejects unsupported (e.g. binary) content types with
WEB_UNSUPPORTED_CONTENT_TYPE.
Config
| Key | Default | Meaning |
|---|---|---|
maxUrlLength | 2048 | Maximum accepted request URL length. |
maxResponseBytes | 5_000_000 | Maximum response body size in bytes. |
maxBodyChars | 100_000 | Maximum decoded body length in characters. |
timeoutMs | 30_000 | Fetch timeout within Node's timer range — a resource backstop for direct ctx.web.fetch() callers, not the model-facing tool-call budget (that is dsh-tool-call-timeout-policy). |
maxRedirects | 5 | Maximum same-origin redirect hops (0 follows none). |
userAgent | deepseek-harness/… | User-Agent header. |
The numeric limits are validated at plugin construction: every cap except maxRedirects must be a positive finite number, and maxRedirects must be a non-negative integer. An invalid value throws rather than silently constructing a provider with nonsensical limits.
Model Experience
Indirectly, through dsh-tool-web, which places this provider's maxBodyChars-bounded decoded text or markdown-shaped HTML under its fetch-result wrapper and retains provider failures while redirects, headers, and transport mechanics remain hidden.
KV Cache effect
No direct invalidation; the named consumer owns any request-prefix changes.
Known Limitations and Deferred Work
- SSRF / private-network protection is deferred — no blocking of private, loopback, link-local, multicast, or otherwise non-public destinations, no DNS-resolve-then-validate, no per-hop re-validation (see the web capability seam Agent Note). Until it lands, this provider is an SSRF primitive and must not be enabled in a deployment that can reach sensitive internal network targets.
- Only textual content decodes — html/xhtml and
text/*-plus-JSON/XML families; a missingContent-Typeor any binary type throwsWEB_UNSUPPORTED_CONTENT_TYPE, and text-extractable PDF decoding is named deferred work. - Charset comes only from the
Content-Typeheader (UTF-8 default) — an HTML<meta charset>declaration is ignored, and a declared-but-unrecognized charset label throws rather than falling back.