summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-09-28 17:57:50 -0400
committerDax Raad <[email protected]>2025-09-28 17:57:50 -0400
commitc148f10bbd0c5a59160050218bcc850c9fb58056 (patch)
tree71d4a9c162ef1466170490abf66bb9fee88c75d5
parent06495ea9640d5e72fc9d418e56c70c5ab19fc41b (diff)
downloadopencode-c148f10bbd0c5a59160050218bcc850c9fb58056.tar.gz
opencode-c148f10bbd0c5a59160050218bcc850c9fb58056.zip
core: improve webfetch tool content negotiation and format handling
-rw-r--r--packages/opencode/src/tool/webfetch.ts35
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: {},
}