From b9edeae961ea341e29fee85fd101f2051e870fd2 Mon Sep 17 00:00:00 2001 From: Tyler Yust Date: Sat, 24 Jan 2026 13:33:33 -0800 Subject: [PATCH] fix: update default chunk mode to 'length' for BlueBubbles - Changed the default value of `chunkMode` from 'newline' to 'length' in the BlueBubbles configuration and related processing functions. - Updated documentation to reflect the new default behavior for chunking messages. - Adjusted tests to ensure the correct default value is returned for BlueBubbles chunk mode. --- docs/channels/bluebubbles.md | 2 +- extensions/bluebubbles/src/accounts.ts | 2 +- extensions/bluebubbles/src/monitor.ts | 4 +++- src/auto-reply/chunk.test.ts | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/channels/bluebubbles.md b/docs/channels/bluebubbles.md index 39a543843..eed40b681 100644 --- a/docs/channels/bluebubbles.md +++ b/docs/channels/bluebubbles.md @@ -196,7 +196,7 @@ Provider options: - `channels.bluebubbles.sendReadReceipts`: Send read receipts (default: `true`). - `channels.bluebubbles.blockStreaming`: Enable block streaming (default: `true`). - `channels.bluebubbles.textChunkLimit`: Outbound chunk size in chars (default: 4000). -- `channels.bluebubbles.chunkMode`: `newline` (default) splits on every newline and sends each line immediately during streaming; `length` splits only when exceeding `textChunkLimit`. +- `channels.bluebubbles.chunkMode`: `length` (default) splits only when exceeding `textChunkLimit`; `newline` splits on every newline and sends each line immediately during streaming. - `channels.bluebubbles.mediaMaxMb`: Inbound media cap in MB (default: 8). - `channels.bluebubbles.historyLimit`: Max group messages for context (0 disables). - `channels.bluebubbles.dmHistoryLimit`: DM history limit. diff --git a/extensions/bluebubbles/src/accounts.ts b/extensions/bluebubbles/src/accounts.ts index 6603b7d2a..9fc94356d 100644 --- a/extensions/bluebubbles/src/accounts.ts +++ b/extensions/bluebubbles/src/accounts.ts @@ -47,7 +47,7 @@ function mergeBlueBubblesAccountConfig( }; const { accounts: _ignored, ...rest } = base; const account = resolveAccountConfig(cfg, accountId) ?? {}; - const chunkMode = account.chunkMode ?? rest.chunkMode ?? "newline"; + const chunkMode = account.chunkMode ?? rest.chunkMode ?? "length"; return { ...rest, ...account, chunkMode }; } diff --git a/extensions/bluebubbles/src/monitor.ts b/extensions/bluebubbles/src/monitor.ts index 1e85a2e5c..8635b183e 100644 --- a/extensions/bluebubbles/src/monitor.ts +++ b/extensions/bluebubbles/src/monitor.ts @@ -1851,7 +1851,7 @@ async function processMessage( account.config.textChunkLimit && account.config.textChunkLimit > 0 ? account.config.textChunkLimit : DEFAULT_TEXT_LIMIT; - const chunkMode = account.config.chunkMode ?? "newline"; + const chunkMode = account.config.chunkMode ?? "length"; const tableMode = core.channel.text.resolveMarkdownTableMode({ cfg: config, channel: "bluebubbles", @@ -1875,7 +1875,9 @@ async function processMessage( sentMessage = true; statusSink?.({ lastOutboundAt: Date.now() }); // In newline mode, restart typing after each chunk if more chunks remain + // Small delay allows the Apple API to finish clearing the typing state from message send if (chunkMode === "newline" && i < chunks.length - 1 && chatGuidForActions) { + await new Promise((r) => setTimeout(r, 150)); sendBlueBubblesTyping(chatGuidForActions, true, { cfg: config, accountId: account.accountId, diff --git a/src/auto-reply/chunk.test.ts b/src/auto-reply/chunk.test.ts index 0e0a25d6d..7a4b41d0e 100644 --- a/src/auto-reply/chunk.test.ts +++ b/src/auto-reply/chunk.test.ts @@ -296,6 +296,7 @@ describe("resolveChunkMode", () => { it("returns length as default", () => { expect(resolveChunkMode(undefined, "telegram")).toBe("length"); expect(resolveChunkMode({}, "discord")).toBe("length"); + expect(resolveChunkMode(undefined, "bluebubbles")).toBe("length"); }); it("returns length for internal channel", () => {