Merge 861be9c936 into 4b5514a259
This commit is contained in:
commit
c09c36485b
@ -6,6 +6,7 @@ Docs: https://docs.molt.bot
|
||||
Status: beta.
|
||||
|
||||
### Changes
|
||||
- WhatsApp: normalize literal `\n` escape sequences to actual newlines in outbound messages. (#3082)
|
||||
- Rebrand: rename the npm package/CLI to `moltbot`, add a `moltbot` compatibility shim, and move extensions to the `@moltbot/*` scope.
|
||||
- Commands: group /help and /commands output with Telegram paging. (#2504) Thanks @hougangdev.
|
||||
- macOS: limit project-local `node_modules/.bin` PATH preference to debug builds (reduce PATH hijacking risk).
|
||||
|
||||
@ -15,7 +15,10 @@ import {
|
||||
shouldSkipDuplicateInbound,
|
||||
} from "./reply/inbound-dedupe.js";
|
||||
import { formatInboundBodyWithSenderMeta } from "./reply/inbound-sender-meta.js";
|
||||
import { normalizeInboundTextNewlines } from "./reply/inbound-text.js";
|
||||
import {
|
||||
normalizeInboundTextNewlines,
|
||||
normalizeOutboundTextNewlines,
|
||||
} from "./reply/inbound-text.js";
|
||||
import { resolveGroupRequireMention } from "./reply/groups.js";
|
||||
import {
|
||||
buildMentionRegexes,
|
||||
@ -69,6 +72,40 @@ describe("normalizeInboundTextNewlines", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("normalizeOutboundTextNewlines", () => {
|
||||
it("keeps real newlines", () => {
|
||||
expect(normalizeOutboundTextNewlines("a\nb")).toBe("a\nb");
|
||||
});
|
||||
|
||||
it("converts literal \\n to real newlines", () => {
|
||||
expect(normalizeOutboundTextNewlines("Hello\\nWorld")).toBe("Hello\nWorld");
|
||||
});
|
||||
|
||||
it("converts multiple literal \\n sequences", () => {
|
||||
expect(normalizeOutboundTextNewlines("Line1\\n\\nLine2")).toBe("Line1\n\nLine2");
|
||||
});
|
||||
|
||||
it("converts literal \\r\\n to real newlines", () => {
|
||||
expect(normalizeOutboundTextNewlines("a\\r\\nb")).toBe("a\nb");
|
||||
});
|
||||
|
||||
it("converts literal \\r to real newlines", () => {
|
||||
expect(normalizeOutboundTextNewlines("a\\rb")).toBe("a\nb");
|
||||
});
|
||||
|
||||
it("handles empty string", () => {
|
||||
expect(normalizeOutboundTextNewlines("")).toBe("");
|
||||
});
|
||||
|
||||
it("handles text without escape sequences", () => {
|
||||
expect(normalizeOutboundTextNewlines("Hello World")).toBe("Hello World");
|
||||
});
|
||||
|
||||
it("handles mixed real and literal newlines", () => {
|
||||
expect(normalizeOutboundTextNewlines("Real\nand\\nliteral")).toBe("Real\nand\nliteral");
|
||||
});
|
||||
});
|
||||
|
||||
describe("finalizeInboundContext", () => {
|
||||
it("fills BodyForAgent/BodyForCommands and normalizes newlines", () => {
|
||||
const ctx: MsgContext = {
|
||||
|
||||
@ -1,3 +1,17 @@
|
||||
export function normalizeInboundTextNewlines(input: string): string {
|
||||
return input.replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll("\\n", "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize outbound text newlines before sending to channels.
|
||||
* Converts literal `\n` escape sequences to actual newlines.
|
||||
* Some LLM providers may output literal `\n` in their responses,
|
||||
* which causes WhatsApp (and potentially other channels) to display
|
||||
* the escape sequence as text instead of rendering a line break.
|
||||
*/
|
||||
export function normalizeOutboundTextNewlines(input: string): string {
|
||||
if (!input) return input;
|
||||
// Convert literal \n (backslash-n) sequences to actual newlines.
|
||||
// Also handle \r\n and \r for consistency.
|
||||
return input.replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n").replaceAll("\\n", "\n");
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { chunkText } from "../../../auto-reply/chunk.js";
|
||||
import { normalizeOutboundTextNewlines } from "../../../auto-reply/reply/inbound-text.js";
|
||||
import { shouldLogVerbose } from "../../../globals.js";
|
||||
import { sendPollWhatsApp } from "../../../web/outbound.js";
|
||||
import { isWhatsAppGroupJid, normalizeWhatsAppTarget } from "../../../whatsapp/normalize.js";
|
||||
@ -60,7 +61,8 @@ export const whatsappOutbound: ChannelOutboundAdapter = {
|
||||
sendText: async ({ to, text, accountId, deps, gifPlayback }) => {
|
||||
const send =
|
||||
deps?.sendWhatsApp ?? (await import("../../../web/outbound.js")).sendMessageWhatsApp;
|
||||
const result = await send(to, text, {
|
||||
const normalizedText = normalizeOutboundTextNewlines(text);
|
||||
const result = await send(to, normalizedText, {
|
||||
verbose: false,
|
||||
accountId: accountId ?? undefined,
|
||||
gifPlayback,
|
||||
@ -70,7 +72,8 @@ export const whatsappOutbound: ChannelOutboundAdapter = {
|
||||
sendMedia: async ({ to, text, mediaUrl, accountId, deps, gifPlayback }) => {
|
||||
const send =
|
||||
deps?.sendWhatsApp ?? (await import("../../../web/outbound.js")).sendMessageWhatsApp;
|
||||
const result = await send(to, text, {
|
||||
const normalizedText = normalizeOutboundTextNewlines(text);
|
||||
const result = await send(to, normalizedText, {
|
||||
verbose: false,
|
||||
mediaUrl,
|
||||
accountId: accountId ?? undefined,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user