diff options
| author | Dax Raad <[email protected]> | 2025-09-28 17:57:50 -0400 |
|---|---|---|
| committer | Dax Raad <[email protected]> | 2025-09-28 17:57:50 -0400 |
| commit | c148f10bbd0c5a59160050218bcc850c9fb58056 (patch) | |
| tree | 71d4a9c162ef1466170490abf66bb9fee88c75d5 | |
| parent | 06495ea9640d5e72fc9d418e56c70c5ab19fc41b (diff) | |
| download | opencode-c148f10bbd0c5a59160050218bcc850c9fb58056.tar.gz opencode-c148f10bbd0c5a59160050218bcc850c9fb58056.zip | |
core: improve webfetch tool content negotiation and format handling
| -rw-r--r-- | packages/opencode/src/tool/webfetch.ts | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/packages/opencode/src/tool/webfetch.ts b/packages/opencode/src/tool/webfetch.ts index 4d1849417..71b09cd95 100644 --- a/packages/opencode/src/tool/webfetch.ts +++ b/packages/opencode/src/tool/webfetch.ts @@ -44,12 +44,29 @@ export const WebFetchTool = Tool.define("webfetch", { const controller = new AbortController() const timeoutId = setTimeout(() => controller.abort(), timeout) + // Build Accept header based on requested format with q parameters for fallbacks + let acceptHeader = "*/*" + switch (params.format) { + case "markdown": + acceptHeader = "text/markdown;q=1.0, text/x-markdown;q=0.9, text/plain;q=0.8, text/html;q=0.7, */*;q=0.1" + break + case "text": + acceptHeader = "text/plain;q=1.0, text/markdown;q=0.9, text/html;q=0.8, */*;q=0.1" + break + case "html": + acceptHeader = "text/html;q=1.0, application/xhtml+xml;q=0.9, text/plain;q=0.8, text/markdown;q=0.7, */*;q=0.1" + break + default: + acceptHeader = + "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8" + } + const response = await fetch(params.url, { signal: AbortSignal.any([controller.signal, ctx.abort]), headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", - Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", + Accept: acceptHeader, "Accept-Language": "en-US,en;q=0.9", }, }) @@ -75,12 +92,14 @@ export const WebFetchTool = Tool.define("webfetch", { const contentType = response.headers.get("content-type") || "" const title = `${params.url} (${contentType})` + + // Handle content based on requested format and actual content type switch (params.format) { - case "text": + case "markdown": if (contentType.includes("text/html")) { - const text = await extractTextFromHTML(content) + const markdown = convertHTMLToMarkdown(content) return { - output: text, + output: markdown, title, metadata: {}, } @@ -91,17 +110,17 @@ export const WebFetchTool = Tool.define("webfetch", { metadata: {}, } - case "markdown": + case "text": if (contentType.includes("text/html")) { - const markdown = convertHTMLToMarkdown(content) + const text = await extractTextFromHTML(content) return { - output: markdown, + output: text, title, metadata: {}, } } return { - output: "```\n" + content + "\n```", + output: content, title, metadata: {}, } |
