diff --git a/README.md b/README.md index effdd3f..a5fbce1 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ message meets a specified criterion. - **Custom system prompts** – tailor the instructions sent to the model for more precise results. - **Persistent result caching** – classification results and reasoning are saved to disk so messages aren't re-evaluated across restarts. - **Advanced parameters** – tune generation settings like temperature, top‑p and more from the options page. +- **Markdown conversion** – optionally convert HTML bodies to Markdown before sending them to the AI service. - **Debug logging** – optional colorized logs help troubleshoot interactions with the AI service. - **Automatic rules** – create rules that tag or move new messages based on AI classification. - **Rule ordering** – drag rules to prioritize them and optionally stop processing after a match. diff --git a/_locales/en-US/messages.json b/_locales/en-US/messages.json index 591373d..172a152 100644 --- a/_locales/en-US/messages.json +++ b/_locales/en-US/messages.json @@ -15,4 +15,5 @@ "template.custom": { "message": "Custom" }, "options.save": { "message": "Save" }, "options.debugLogging": { "message": "Enable debug logging" } + ,"options.htmlToMarkdown": { "message": "Convert HTML body to Markdown" } } diff --git a/background.js b/background.js index d0425c2..2021990 100644 --- a/background.js +++ b/background.js @@ -22,6 +22,8 @@ let iconTimer = null; let timingStats = { count: 0, mean: 0, m2: 0, total: 0, last: -1 }; let currentStart = 0; let logGetTiming = true; +let htmlToMarkdown = false; +let TurndownService = null; function setIcon(path) { if (browser.browserAction) { @@ -70,7 +72,17 @@ function collectText(part, bodyParts, attachments) { attachments.push(`${name} (${ct}, ${part.size || byteSize(body)} bytes)`); } else if (ct.startsWith("text/html")) { const doc = new DOMParser().parseFromString(body, 'text/html'); - bodyParts.push(replaceInlineBase64(doc.body.textContent || "")); + if (htmlToMarkdown && TurndownService) { + try { + const td = new TurndownService(); + const md = td.turndown(doc.body.innerHTML || body); + bodyParts.push(replaceInlineBase64(`[HTML Body converted to Markdown]\n${md}`)); + } catch (e) { + bodyParts.push(replaceInlineBase64(doc.body.textContent || "")); + } + } else { + bodyParts.push(replaceInlineBase64(doc.body.textContent || "")); + } } else { bodyParts.push(replaceInlineBase64(body)); } @@ -213,16 +225,19 @@ async function clearCacheForMessages(idsInput) { try { AiClassifier = await import(browser.runtime.getURL("modules/AiClassifier.js")); logger.aiLog("AiClassifier imported", {debug: true}); + const td = await import(browser.runtime.getURL("resources/js/turndown.js")); + TurndownService = td.default || td.TurndownService; } catch (e) { console.error("failed to import AiClassifier", e); return; } try { - const store = await storage.local.get(["endpoint", "templateName", "customTemplate", "customSystemPrompt", "aiParams", "debugLogging", "aiRules"]); + const store = await storage.local.get(["endpoint", "templateName", "customTemplate", "customSystemPrompt", "aiParams", "debugLogging", "htmlToMarkdown", "aiRules"]); logger.setDebug(store.debugLogging); await AiClassifier.setConfig(store); await AiClassifier.init(); + htmlToMarkdown = store.htmlToMarkdown === true; const savedStats = await storage.local.get('classifyStats'); if (savedStats.classifyStats && typeof savedStats.classifyStats === 'object') { Object.assign(timingStats, savedStats.classifyStats); @@ -254,6 +269,10 @@ async function clearCacheForMessages(idsInput) { }); logger.aiLog("aiRules updated from storage change", {debug: true}, aiRules); } + if (changes.htmlToMarkdown) { + htmlToMarkdown = changes.htmlToMarkdown.newValue === true; + logger.aiLog("htmlToMarkdown updated from storage change", {debug: true}, htmlToMarkdown); + } }); } catch (err) { logger.aiLog("failed to load config", {level: 'error'}, err); diff --git a/options/options.html b/options/options.html index cb9668a..e285a22 100644 --- a/options/options.html +++ b/options/options.html @@ -98,6 +98,11 @@ Enable debug logging +