{"_id":"@buckeyestudio/toh-web-fetch-http","name":"@buckeyestudio/toh-web-fetch-http","dist-tags":{"next":"0.1.1-rc.2","latest":"0.1.1-rc.2"},"versions":{"0.1.1-rc.2":{"name":"@buckeyestudio/toh-web-fetch-http","description":"Anonymous public HTTP(S) fetch provider for the TheOpen Harness web capability seam (ctx.web)","version":"0.1.1-rc.2","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/web/web-fetch-http"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","author":{"name":"buckeyestudio"},"peerDependencies":{"@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-timeout":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1","@buckeyestudio/toh-web":"^0.1.1-rc.2"},"dependencies":{"@buckeyestudio/schemastery":"^3.18.1"},"devDependencies":{"@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-timeout":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1","@buckeyestudio/toh-web":"^0.1.1-rc.2"},"_id":"@buckeyestudio/toh-web-fetch-http@0.1.1-rc.2","bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","_integrity":"sha512-36/fQbdpmtJ65e6N2PHavv9mk7dNPkJYKbW9HivUBEXAA199LJTHxu8k1Q2d0YmXPDTcya8qhI+NT/3MOxgj2A==","_resolved":"/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-web-fetch-http-0.1.1-rc.2.tgz","_from":"file:/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-web-fetch-http-0.1.1-rc.2.tgz","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-36/fQbdpmtJ65e6N2PHavv9mk7dNPkJYKbW9HivUBEXAA199LJTHxu8k1Q2d0YmXPDTcya8qhI+NT/3MOxgj2A==","shasum":"e73fbe7f8ca38c963da95209e418fd9cc02f1a66","tarball":"https://registry.npmjs.org/@buckeyestudio/toh-web-fetch-http/-/toh-web-fetch-http-0.1.1-rc.2.tgz","fileCount":11,"unpackedSize":37598,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC9NkagAxzGHCBDQdIjqOuFiT5IopJDOWxkycAhn2o3hAiAaNJI9BPB0PVJLdAOyEaOhcuDgszxPnOnt4UwOqAOpgg=="}]},"_npmUser":{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"},"directories":{},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/toh-web-fetch-http_0.1.1-rc.2_1787489891807_0.1344383917510894"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T12:58:11.661Z","0.1.1-rc.2":"2026-08-23T12:58:11.947Z","modified":"2026-08-23T12:58:12.143Z"},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"description":"Anonymous public HTTP(S) fetch provider for the TheOpen Harness web capability seam (ctx.web)","homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/web/web-fetch-http"},"author":{"name":"buckeyestudio"},"bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"license":"MIT","readme":"# @buckeyestudio/toh-web-fetch-http\n\n[English](README.md) | 中文\n\n一个匿名公共 HTTP(S) `WebFetchProvider`，用于 harness [web 能力 seam](../web/README.zh.md)（`ctx.web`）。它获取具体 URL，返回状态码和长度受限的解码内容。\n\n这是一个**实现**包：它向 `ctx.web` 注册提供方，不拥有该键，也不注册面向模型的工具。它是函数／命名空间插件（`inject: ['web']`）。\n\n## 职责拆分\n\n提供方拥有**安全资源获取**：URL 验证、HTTP 传输、重定向策略、资源兜底超时、中止传播、字节上限、charset 解码、内容类型分类与二进制拒绝。`@buckeyestudio/toh-tool-web` 拥有**呈现**（HTML→markdown、截断格式）。非 2xx HTTP 响应是*结果*（状态码 + 解码主体），不是错误；`WebError` 只用于无法安全获取或表示资源的失败。\n\n提供方的 `timeoutMs` 是直接 `ctx.web.fetch()` 调用方和配置有误的部署所用的资源兜底，不是面向模型的工具调用预算。[`toh-tool-call-timeout-policy`](../../guard/timeout-policy/README.zh.md) 拥有 `web_fetch` 工具调用预算，并让 `exec.signal` 在超时时触发，以强制执行该预算。\n\n已交付的 web 工具部署会把提供方兜底设为高于工具预算，因此模型调用通常返回 `TOOL_TIMEOUT`。如果外层截止期限先于提供方的兜底超时触发，提供方会报告 `WEB_ABORTED`，外层策略再将其替换为 `TOOL_TIMEOUT`。因此，`WEB_FETCH_TIMEOUT` 表明直接服务调用方的提供方预算已经耗尽。\n\n## 传输卫生\n\n- 只接受 `http:` 和 `https:` URL；拒绝 URL 中的凭据（`WEB_BLOCKED_URL`）以及过长／格式错误的 URL（`WEB_INVALID_URL`）。\n- 强制执行 URL 最大长度、响应字节上限（`WEB_FETCH_TOO_LARGE`）、解码主体字符上限、超时（`WEB_FETCH_TIMEOUT`）和重定向跳数上限。\n- 把调用方的中止信号（`WEB_ABORTED`）传播到网络请求与流式读取。\n- 只跟随**同源**重定向；跨源重定向以 `WEB_REDIRECT_BLOCKED` 失败，要求发起新的工具调用（沿用 Claude Code 的 WebFetch 模式）。\n- 发送显式的产品 `User-Agent`，绝不伪装成浏览器。\n- 不受支持的内容类型（例如二进制）以 `WEB_UNSUPPORTED_CONTENT_TYPE` 拒绝。\n\n## 配置\n\n| 配置键 | 默认值 | 含义 |\n|---|---|---|\n| `maxUrlLength` | `2048` | 接受的请求 URL 最大长度。 |\n| `maxResponseBytes` | `5_000_000` | 响应主体最大字节数。 |\n| `maxBodyChars` | `100_000` | 解码主体最大字符数。 |\n| `timeoutMs` | `30_000` | Node 定时器范围内的抓取超时：直接 `ctx.web.fetch()` 调用方的资源兜底，而非面向模型的工具调用预算（后者属于 `toh-tool-call-timeout-policy`）。 |\n| `maxRedirects` | `5` | 同源重定向最大跳数（`0` 表示完全不跟随）。 |\n| `userAgent` | `theopen-harness/…` | `User-Agent` 标头。 |\n\n数值限制会在插件构造时验证：除 `maxRedirects` 外，每个上限都必须是正的有限数；`maxRedirects` 必须是非负整数。无效值会抛出异常，不会静默构造限制荒谬的提供方。\n\n## 模型体验\n\n通过 [`toh-tool-web`](../tool-web/README.zh.md) 间接影响；该工具把此提供方经 `maxBodyChars` 限制的解码文本或由 HTML 转换得到的 markdown 置于抓取结果包装层中，并保留提供方失败；重定向、标头与传输机制保持隐藏。\n\n#### KV Cache 影响\n\n不会直接导致 KV Cache 失效；请求前缀变更由上述消费方负责。\n\n## 已知限制与暂缓事项\n\n- **SSRF／私有网络防护暂缓**：不会阻止私有、loopback、link-local、multicast 或其他非公开目标，也不进行 DNS 解析后验证或逐跳重新验证（见 [web 能力 seam Agent Note](../../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.zh.md)）。在此功能落地前，该提供方是 SSRF 原语；能够访问敏感内部网络目标的部署**禁止启用它**。\n- **只解码文本内容**：包括 html/xhtml 与 `text/*` 加 JSON/XML 家族；缺少 `Content-Type` 或任何二进制类型都会抛出 `WEB_UNSUPPORTED_CONTENT_TYPE`，可提取文本的 PDF 解码属于明确的暂缓工作。\n- **charset 只来自 `Content-Type` 标头**（默认为 UTF-8）：HTML `<meta charset>` 声明会被忽略；声明但无法识别的 charset 标签会抛出异常，而非回退。\n","readmeFilename":"README.zh.md","_rev":"1-bff5b38c9fea01d84cf44d0824cf770b"}