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