WebFetchTool / WebSearchTool: Die Netzwerk-Werkzeuge des Cline-Kontos
Verantwortung
Diese beiden Handler sind die Netzwerk-Ausgangs-Werkzeuge von Cline; beide implementieren IFullyManagedTool und verlangen vor der Ausführung, dass der Provider cline ist und der Nutzer die Einstellung clineWebToolsEnabled aktiviert hat und das zugehörige Feature Flag gesetzt ist (WebFetch class:20-21,WebSearch class:21-22). Der wesentliche Unterschied zum BrowserToolHandler: Das Browser-Werkzeug ruft Seiten direkt über ein lokales oder Remote-Chrome ab, während diese beiden Werkzeuge HTTP-Anfragen an die offizielle Cline-API senden und den Cline-Server das Fetchen oder Suchen übernehmen lassen, bevor das Ergebnis an das Modell zurückfließt.
- WebFetchToolHandler (
ClineDefaultTool.WEB_FETCH): Das Modell liefert eine URL und einen prompt; das Werkzeug POSTet beilde an${apiBaseUrl}/api/v1/search/webfetch; der Server extrahiert mit dem prompt den Inhalt der URL und gibt einen Textergebnis zurück (webfetch axios:150). - WebSearchToolHandler (
ClineDefaultTool.WEB_SEARCH): Das Modell liefert eine query sowie optionalallowed_domains/blocked_domainsals Whitelist/Blacklist (gegenseitig ausschließend); das Werkzeug POSTet an/api/v1/search/websearchund gibt eine Liste von {title, url}-Ergebnissen zurück (websearch axios:174).
Die Ausgabe beider Werkzeuge wird dem Nutzer nicht direkt angezeigt, sondern lediglich als tool result in den userMessageContent für die nächste LLM-Runde eingefügt. Sie benötigen keine lokalen Ressourcen (Dateisystem, Terminal, Browser) und sind reine Netzwerk-Ausgänge, daher operationIsLocatedInWorkspace: false.
Entwurfsmotivation
- Serverseitiger Proxy statt lokales Fetch: In vielen Szenarien läuft Cline in einer eingeschränkten Umgebung ohne direkten Internetzugang; der serverseitige Proxy übernimmt einheitliche Authentifizierung, einheitliches Rate-Limiting und einheitliche Fetch-Logik (JavaScript-Rendering, Anti-Crawler-Umgehung), der Client sendet nur Anfragen (
webfetch request:150-166). - Drei Tore: Provider muss cline sein, Nutzer muss clineWebToolsEnabled gesetzt und das Feature Flag aktiv haben; trifft eines nicht zu, wird direkt
toolError("Cline web tools are currently disabled.")zurückgegeben, damit das Modell nicht weiterläuft (feature flag gate:55-59). - 15-Sekunden-Timeout: Beide Werkzeuge nutzen ein 15-Sekunden-axios-Timeout, damit langes Anfrageverhalten nicht die gesamte Runde blockiert (
timeout:163). - Gegenseitiger Ausschluss von Domain-Whitelist/Blacklist: web_search validiert, dass
allowed_domainsundblocked_domainsnicht gleichzeitig angegeben werden; bei Verstoßmistake+++ toolError (mutual exclusivity:75-78). - Parsing von partiellen Arrays im Stream:
parsePartialArrayStringkann auch bei unvollständigem JSON wie["a", "b"bereits die vollständigen Elemente extrahieren, sodass die Domain-Liste schon in der partial-block-Phase angezeigt wird (parsePartialArrayString:71-72). - Explizite Auth-Fehlermeldung: Wenn das auth token nicht geholt werden kann, wird
CLINE_ACCOUNT_AUTH_ERROR_MESSAGEgeworfen, das den Nutzer auffordert, sich in sein Cline-Konto einzuloggen, anstatt dem Modell eine 401 zu schicken (auth check:146-148).
Schlüsseldateien
WebFetch class:20—name = ClineDefaultTool.WEB_FETCH.handlePartialBlock:27— Sagt während des Streams nur einen „Fetching URL: ..."-Placeholder, ohne zu blockieren.execute:44— Hauptfluss: gate → Parameter-Validierung → Approval → hook → axios POST → Ergebnis zurückgeben.feature flag gate:55-59— provider !== "cline" oder setting/flag gleich false: direkt toolError.approval flow:81-128—shouldAutoApproveToolentscheidet zwischen say und ask.axios POST webfetch:143-166— Holt baseUrl + authToken, POST/api/v1/search/webfetch, body{Url, Prompt}, header trägtX-Task-ID.WebSearch class:21—name = ClineDefaultTool.WEB_SEARCH.domain parse + mutex:70-78—parsePartialArrayStringparst das Domain-Array + gegenseitiger Ausschluss.axios POST websearch:150-183— POST/api/v1/search/websearch, body nimmt die entsprechenden Felder nur auf, wenn das Array nicht leer ist.format results:188-200— Setzt{title, url}[]in das Textformat1. title\n url\n\num.CLINE_ACCOUNT_AUTH_ERROR_MESSAGE— Einheitlicher Hinweistext für Auth-Fehler.AuthService—getInstance().getAuthToken()holt das Token des aktuellen Kontos.
Datenfluss
Der Ablauf beider Handler ist nahezu identisch; am Beispiel WebFetchToolHandler ist der Kern der POST nach Approval an die Cline-API:
// 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() fügt zusätzliche Tracking-Header hinzu, getAxiosSettings() injiziert Proxy/CA und andere Nutzerkonfigurationen in axios. Die Antwortstruktur ist { data: { result: "..." } } (axios hat automatisch eine data-Schicht hinzugefügt); das Resultat wird direkt herausgeholt und mit formatResponse.toolResult als tool result an die LLM zurückgegeben.
WebSearchToolHandler hat einen zusätzlichen Schritt zur Ergebnis-Formatierung:
// 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 werden im Request-Body nur dann gesetzt, wenn sie nicht leer sind; der gegenseitige Ausschluss wird nach mistake++ direkt als toolError abgelehnt, ohne eine Anfrage zu senden.
Grenzen und Fehler
- Drei Tore nicht erfüllt: provider nicht cline, Web-Tools-Einstellung vom Nutzer deaktiviert oder Feature Flag aus — bei jedem trifft direkt ein disabled-toolError zu, ohne
mistakezu inkrementieren (feature flag gate:55-59). - Nicht eingeloggt: Wenn
AuthService.getInstance().getAuthToken()leer zurückgibt, wirdCLINE_ACCOUNT_AUTH_ERROR_MESSAGEgeworfen und im catch-Block inError fetching web content: ...umgewandelt (auth check:146-148). - Whitelist und Blacklist gleichzeitig: Wenn web_search
allowed_domainsundblocked_domainsgleichzeitig erhält, erfolgtmistake+++ toolError und direkte Blockade (mutual exclusivity:75-78). - PreToolUse hook bricht ab: Wirft der Hook
PreToolUseHookCancellationError, wird toolDenied zurückgegeben, ohne eine Anfrage zu senden (PreToolUse hook:131-140). - Fallback bei Anfrage-Fehlern: Wirft axios oder der Server nicht 200, wird im catch-Block als
Error fetching web content: .../Error performing web search: ...verpackt, ohne an die Task zu werfen, damit das Modell den Fehler sieht (error catch:173-175). - Timeout: 15 Sekunden axios-Timeout; lange Anfragen werden abgeschnitten und laufen durch den error-catch (
timeout:163). - Leere Ergebnisse: Wenn web_search 0 Ergebnisse zurückgibt, wird
Search completed (0 results found)ohne weitere Zeilen geliefert (empty results:193-199).
Zusammenfassung
WebFetch und WebSearch sind die beiden Handler, über die Cline Fetching und Suche über seinen eigenen Server-Proxy abwickelt. Sie teilen sich dasselbe Gate (provider=cline + setting + flag), denselben Approval-/Hook-Ablauf und dasselbe 15-Sekunden-Timeout. WebFetch liefert den vom Server mit dem prompt extrahierten Text, WebSearch liefert eine strukturierte {title, url}-Liste und formatiert sie als Text im Format 1./2./3. Beide Werkzeuge schreiben nicht auf die Platte und öffnen keinen Browser — es handelt sich um reinen Netzwerk-Ausgang.
Wer tiefer einsteigen will, kann weiterlesen bei:
- Browser-Werkzeug (lokales Fetch):
/cap-tools/browser - Datei- und Befehls-Werkzeuge:
/cap-tools/file-ops - Werkzeug-Dispatch-Pfad:
/agent-loop/task-class
Siehe offizielle Dokumentation: Cline-Dokumentation · README