Skip to content

WebFetchTool / WebSearchTool:Cline 账号的网络工具

源码版本v4.0.10

职责

这两个 handler 是 Cline 的网络出口工具,都实现 IFullyManagedTool,都在执行前要求 provider 是 cline 且用户开了 clineWebToolsEnabled 设置且对应 feature flag 开启(WebFetch class:20-21,WebSearch class:21-22)。它们和 BrowserToolHandler 的本质区别是:浏览器工具是本地或远程 Chrome 直接抓页面,这两个工具是发 HTTP 请求到 Cline 官方 API,让 Cline 服务端做抓取或搜索,再把结果回给模型。

  • WebFetchToolHandler(ClineDefaultTool.WEB_FETCH):模型给一个 URL 和一个 prompt,工具把这两者 POST 到 ${apiBaseUrl}/api/v1/search/webfetch,服务端用 prompt 抽取 URL 内容并返回一段文本结果(webfetch axios:150).
  • WebSearchToolHandler(ClineDefaultTool.WEB_SEARCH):模型给一个 query 和可选的 allowed_domains/blocked_domains 白黑名单(互斥),工具 POST 到 /api/v1/search/websearch,返回一组 {title, url} 结果(websearch axios:174).

这两个工具的输出都不直接呈现给用户,只作为 tool result 塞回 userMessageContent 给下一轮 LLM。它们不需要本地资源(文件系统、terminal、浏览器),完全是网络出口,所以 operationIsLocatedInWorkspace: false

设计动机

  • 服务端代理而非本地抓:很多场景里 Cline 跑在受限环境,直连外网不通;服务端代理统一鉴权、统一限速、统一抓取逻辑(JavaScript 渲染、反爬绕过),客户端只发请求(webfetch request:150-166)。
  • 三闸门:provider 必须是 cline、用户设置 clineWebToolsEnabled、feature flag 开启,任一不满足直接返回 toolError("Cline web tools are currently disabled."),不让模型继续(feature flag gate:55-59)。
  • 15 秒超时:两个工具都用 15 秒 axios 超时,避免长尾请求拖死整轮(timeout:163)。
  • 域名白黑名单互斥:web_search 校验 allowed_domainsblocked_domains 不能同时给,违反时 mistake++ + toolError(mutual exclusivity:75-78)。
  • 流式部分数组解析:parsePartialArrayString 在流式吐 ["a", "b" 这种不完整 JSON 时也能提取已完整的元素,让 partial block 阶段就能显示域名列表(parsePartialArrayString:71-72).
  • 认证错误明确化:auth token 取不到时抛 CLINE_ACCOUNT_AUTH_ERROR_MESSAGE,告知用户去登录 Cline 账号,而不是发 401 给模型(auth check:146-148).

关键文件

数据流

两个 handler 的流程几乎一致,以 WebFetchToolHandler 为例,核心是审批后 POST 到 Cline API:

typescript
// apps/vscode/src/core/task/tools/handlers/WebFetchToolHandler.ts
const baseUrl = ClineEnv.config().apiBaseUrl
const authToken = await AuthService.getInstance().getAuthToken()
if (!authToken) {
    throw new Error(CLINE_ACCOUNT_AUTH_ERROR_MESSAGE)
}

const response = await axios.post(
    `${baseUrl}/api/v1/search/webfetch`,
    { Url: url, Prompt: prompt },
    {
        headers: {
            Authorization: `Bearer ${authToken}`,
            "Content-Type": "application/json",
            "X-Task-ID": config.ulid || "",
            ...(await buildClineExtraHeaders()),
        },
        timeout: 15000,
        ...getAxiosSettings(),
    },
)
const result = response.data.data.result
return formatResponse.toolResult(result)

buildClineExtraHeaders() 加额外追踪头,getAxiosSettings() 给 axios 注入代理/CA 等用户配置。响应结构是 { data: { result: "..." } }(注意 axios 自动加了一层 data 包裹),直接取出来用 formatResponse.toolResult 包成 tool result 回给 LLM。

WebSearchToolHandler 多一步结果格式化:

typescript
// apps/vscode/src/core/task/tools/handlers/WebSearchToolHandler.ts
const data = response.data.data
const results = data.results || []
let resultText = `Search completed (${resultCount} results found)`
if (results.length > 0) {
    resultText += ":\n\n"
    results.forEach((result, index) => {
        resultText += `${index + 1}. ${result.title}\n   ${result.url}\n\n`
    })
}
return formatResponse.toolResult(resultText)

allowed_domains / blocked_domains 在请求体里只在非空时才带,互斥校验在 mistake++ 后直接 toolError 拒掉,不发请求。

边界与失败

  • 三闸门未满足:provider 非 cline、用户关了 web tools 设置、feature flag 关闭,任一为否直接返回 disabled toolError,mistake 不增(feature flag gate:55-59)。
  • 未登录:AuthService.getInstance().getAuthToken() 返回空时抛 CLINE_ACCOUNT_AUTH_ERROR_MESSAGE,在 catch 里被转成 Error fetching web content: ...(auth check:146-148)。
  • 域名白黑名单同给:web_search 同时给 allowed_domainsblocked_domainsmistake++ + toolError,直接拦截(mutual exclusivity:75-78)。
  • PreToolUse hook 取消:hook 抛 PreToolUseHookCancellationError 时返回 toolDenied,不发请求(PreToolUse hook:131-140)。
  • 请求失败兜底:axios 抛错或服务端非 200,catch 里包成 Error fetching web content: ... / Error performing web search: ...,不向 Task 抛,让模型看错误(error catch:173-175)。
  • 超时:15 秒 axios 超时,长尾请求被掐断并走 error catch(timeout:163)。
  • 结果空:web_search 返回 0 结果时返回 Search completed (0 results found),不带后续行(empty results:193-199)。

小结

WebFetch 和 WebSearch 是 Cline 通过自家服务端代理做网络抓取/搜索的两个 handler,共享同一套 gate(provider=cline + setting + flag)、同一套审批/hook 流程、同一个 15 秒超时。WebFetch 返回服务端用 prompt 抽取后的文本,WebSearch 返回结构化的 {title, url} 列表并按 1./2./3. 格式拼成文本。两个工具都不写盘、不开浏览器,完全是纯网络出口。

想往里钻可以接着看:

  • 浏览器工具(本地抓取):/cap-tools/browser
  • 文件与命令工具:/cap-tools/file-ops
  • 工具调度链路:/agent-loop/task-class

对照官方资料:Cline 文档 · README