diff --git a/packages/opencode/src/session/compaction.ts b/packages/opencode/src/session/compaction.ts index 42bab2eb975..6a4c9b9e143 100644 --- a/packages/opencode/src/session/compaction.ts +++ b/packages/opencode/src/session/compaction.ts @@ -27,6 +27,10 @@ export namespace SessionCompaction { ), } + export const PRUNE_MINIMUM = 20_000 + export const PRUNE_PROTECT = 40_000 + export const OVERHEAD_BUFFER = 50_000 + export async function isOverflow(input: { tokens: MessageV2.Assistant["tokens"]; model: Provider.Model }) { const config = await Config.get() if (config.compaction?.auto === false) return false @@ -34,13 +38,10 @@ export namespace SessionCompaction { if (context === 0) return false const count = input.tokens.input + input.tokens.cache.read + input.tokens.output const output = Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) || SessionPrompt.OUTPUT_TOKEN_MAX - const usable = context - output + const usable = context - output - OVERHEAD_BUFFER return count > usable } - export const PRUNE_MINIMUM = 20_000 - export const PRUNE_PROTECT = 40_000 - const PRUNE_PROTECTED_TOOLS = ["skill"] // goes backwards through parts until there are 40_000 tokens worth of tool diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index fd7f8aa72a5..23a0e513b1e 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -773,12 +773,17 @@ export namespace SessionPrompt { // Add support for other types if needed } + const text = textParts.join("\n\n") + const output = text.length > 30_000 + ? text.slice(0, 30_000) + `\n\n[MCP output truncated: exceeded 30000 char limit]` + : text + return { title: "", metadata: result.metadata ?? {}, - output: textParts.join("\n\n"), + output, attachments, - content: result.content, // directly return content to preserve ordering when outputting to model + content: result.content, } } item.toModelOutput = (result) => { diff --git a/packages/opencode/src/tool/webfetch.ts b/packages/opencode/src/tool/webfetch.ts index 634c68f4eea..e1e713fb283 100644 --- a/packages/opencode/src/tool/webfetch.ts +++ b/packages/opencode/src/tool/webfetch.ts @@ -87,53 +87,19 @@ export const WebFetchTool = Tool.define("webfetch", { const contentType = response.headers.get("content-type") || "" const title = `${params.url} (${contentType})` + const isHtml = contentType.includes("text/html") - // Handle content based on requested format and actual content type - switch (params.format) { - case "markdown": - if (contentType.includes("text/html")) { - const markdown = convertHTMLToMarkdown(content) - return { - output: markdown, - title, - metadata: {}, - } - } - return { - output: content, - title, - metadata: {}, - } + const raw = params.format === "markdown" && isHtml + ? convertHTMLToMarkdown(content) + : params.format === "text" && isHtml + ? await extractTextFromHTML(content) + : content - case "text": - if (contentType.includes("text/html")) { - const text = await extractTextFromHTML(content) - return { - output: text, - title, - metadata: {}, - } - } - return { - output: content, - title, - metadata: {}, - } + const output = raw.length > 30_000 + ? raw.slice(0, 30_000) + `\n\n[Output truncated: exceeded 30000 char limit]` + : raw - case "html": - return { - output: content, - title, - metadata: {}, - } - - default: - return { - output: content, - title, - metadata: {}, - } - } + return { output, title, metadata: {} } }, })