diff --git a/src/channel/openclaw-sdk-untyped.d.ts b/src/channel/openclaw-sdk-untyped.d.ts index 3e9aea8..ad2954a 100644 --- a/src/channel/openclaw-sdk-untyped.d.ts +++ b/src/channel/openclaw-sdk-untyped.d.ts @@ -35,8 +35,6 @@ declare module "openclaw/plugin-sdk/plugin-state-runtime" { declare module "openclaw/plugin-sdk/web-content-extractor" { /** Converts sanitized HTML into coarse markdown plus an optional title. */ export function htmlToMarkdown(html: string): { text: string; title?: string }; - /** Removes markdown decoration for plain text extraction. */ - export function markdownToText(markdown: string): string; } declare module "openclaw/plugin-sdk/outbound-media" { diff --git a/src/channel/src/inbound-sdk-compat.test.ts b/src/channel/src/inbound-sdk-compat.test.ts new file mode 100644 index 0000000..6dc0772 --- /dev/null +++ b/src/channel/src/inbound-sdk-compat.test.ts @@ -0,0 +1,51 @@ +import type { AgentMail } from "agentmail"; +import { describe, expect, it, vi } from "vitest"; + +// OpenClaw 2026.10.5-beta.2 no longer exports markdownToText from this SDK subpath. +vi.mock("openclaw/plugin-sdk/web-content-extractor", async (importOriginal) => { + const { htmlToMarkdown } = + await importOriginal(); + return { htmlToMarkdown }; +}); + +import { resolveAgentMailMessageText } from "./inbound.js"; + +describe("AgentMail HTML with the current OpenClaw SDK exports", () => { + it.each(["extractedHtml", "html"] as const)("converts %s without markdownToText", (field) => { + const message = { + [field]: '

Next steps

', + } as AgentMail.Message; + + expect(resolveAgentMailMessageText(message)).toBe( + "## Next steps\n\n- Read [the guide](https://example.com/guide)", + ); + }); + + it("prefers extracted HTML over quoted plain-text history", () => { + expect( + resolveAgentMailMessageText({ + extractedHtml: "

New reply

", + text: "New reply\n\nOld quoted history", + html: "

Old HTML history

", + } as AgentMail.Message), + ).toBe("New reply"); + }); + + it("falls back to plain text when extracted HTML has no visible content", () => { + expect( + resolveAgentMailMessageText({ + extractedHtml: "", + text: "Plain-text reply", + } as AgentMail.Message), + ).toBe("Plain-text reply"); + }); + + it("falls back to the subject when HTML has no visible content", () => { + expect( + resolveAgentMailMessageText({ + html: "", + subject: " Subject-only request ", + } as AgentMail.Message), + ).toBe("Subject-only request"); + }); +}); diff --git a/src/channel/src/inbound.ts b/src/channel/src/inbound.ts index 2d46ccb..a9d1674 100644 --- a/src/channel/src/inbound.ts +++ b/src/channel/src/inbound.ts @@ -3,7 +3,7 @@ import { AgentMailError, type AgentMail, type AgentMailClient } from "agentmail" import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import type { PluginRuntime } from "openclaw/plugin-sdk/plugin-runtime"; import { buildAgentSessionKey, parseAgentSessionKey } from "openclaw/plugin-sdk/routing"; -import { htmlToMarkdown, markdownToText } from "openclaw/plugin-sdk/web-content-extractor"; +import { htmlToMarkdown } from "openclaw/plugin-sdk/web-content-extractor"; import type { AgentMailLog } from "./log.js"; import { createAgentMailClient } from "./client.js"; import { isAgentMailSenderAllowed, parseSingleFromMailbox } from "./mailbox.js"; @@ -135,7 +135,7 @@ export function resolveAgentMailMessageText(message: AgentMail.Message): string } const extractedHtml = message.extractedHtml?.trim(); const extractedHtmlText = extractedHtml - ? markdownToText(htmlToMarkdown(extractedHtml).text).trim() + ? htmlToMarkdown(extractedHtml).text.trim() : ""; if (extractedHtmlText) { return extractedHtmlText; @@ -145,7 +145,7 @@ export function resolveAgentMailMessageText(message: AgentMail.Message): string return text; } const html = message.html?.trim(); - const htmlText = html ? markdownToText(htmlToMarkdown(html).text).trim() : ""; + const htmlText = html ? htmlToMarkdown(html).text.trim() : ""; return htmlText || message.subject?.trim() || ""; }