Files
deepseek-harness/packages/web/web-fetch-local
Dudu-0223 a1624530ee fix: address codex review round 3
Resource-lifecycle and error-classification fixes in the local fetch provider:

- Classify a timeout that fires DURING the body read as WEB_FETCH_TIMEOUT, not
  WEB_ABORTED: thread the controller signal into the body-read translate path
  and recover the timeout WebError from signal.reason, honoring the public
  WEB_FETCH_TIMEOUT contract for a stalled response body.
- Cancel the response body before every blocked-redirect throw path
  (cross-origin, invalid target, missing Location), so a rejected redirect with
  a large or streaming body does not leak the socket after the tool returns
  WEB_REDIRECT_BLOCKED.
- Cancel the body when charset validation fails, matching the
  unsupported-content-type and over-size paths (the round-1 charset check threw
  before readCapped owned the stream).
2026-06-26 19:14:30 +08:00
..
2026-06-26 19:14:30 +08:00
2026-06-26 19:14:30 +08:00

@deepseek-ai/dsh-web-fetch-local

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, 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.

Transport hygiene

  • Accepts only http: and https: 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 Default fetch timeout.
maxTimeoutMs 120_000 Upper bound for a per-request timeout override.
maxRedirects 5 Maximum same-origin redirect hops.
userAgent deepseek-harness/… User-Agent header.

Security note

SSRF / private-network protection (blocking private, loopback, link-local, multicast, and otherwise non-public destinations, with DNS-resolve-then-validate and per-hop re-validation) is deferred — see the web capability seam RFC. Until it lands, this provider is an SSRF primitive and must not be enabled in a deployment that can reach sensitive internal network targets.