feat: add chunking mode option for BlueBubbles (#1645)

* feat: add chunking mode for outbound messages

- Introduced `chunkMode` option in various account configurations to allow splitting messages by "length" or "newline".
- Updated message processing to handle chunking based on the selected mode.
- Added tests for new chunking functionality, ensuring correct behavior for both modes.

* feat: enhance chunking mode documentation and configuration

- Added `chunkMode` option to the BlueBubbles account configuration, allowing users to choose between "length" and "newline" for message chunking.
- Updated documentation to clarify the behavior of the `chunkMode` setting.
- Adjusted account merging logic to incorporate the new `chunkMode` configuration.

* refactor: simplify chunk mode handling for BlueBubbles

- Removed `chunkMode` configuration from various account schemas and types, centralizing chunk mode logic to BlueBubbles only.
- Updated `processMessage` to default to "newline" for BlueBubbles chunking.
- Adjusted tests to reflect changes in chunk mode handling for BlueBubbles, ensuring proper functionality.

* 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.
This commit is contained in:
Tyler Yust
2026-01-24 16:47:10 -08:00
committed by GitHub
parent 6375ee836f
commit 92e794dc18
13 changed files with 247 additions and 8 deletions

View File

@@ -7,7 +7,7 @@ import {
INTERNAL_MESSAGE_CHANNEL,
listDeliverableMessageChannels,
} from "../../utils/message-channel.js";
import { resolveTextChunkLimit, type TextChunkProvider } from "../chunk.js";
import { resolveChunkMode, resolveTextChunkLimit, type TextChunkProvider } from "../chunk.js";
const DEFAULT_BLOCK_STREAM_MIN = 800;
const DEFAULT_BLOCK_STREAM_MAX = 1200;
@@ -68,6 +68,17 @@ export function resolveBlockStreamingChunking(
fallbackLimit: providerChunkLimit,
});
const chunkCfg = cfg?.agents?.defaults?.blockStreamingChunk;
// BlueBubbles-only: if chunkMode is "newline", use newline-based streaming
const channelChunkMode = resolveChunkMode(cfg, providerKey, accountId);
if (channelChunkMode === "newline") {
// For newline mode: use very low minChars to flush quickly on newlines
const minChars = Math.max(1, Math.floor(chunkCfg?.minChars ?? 1));
const maxRequested = Math.max(1, Math.floor(chunkCfg?.maxChars ?? textLimit));
const maxChars = Math.max(1, Math.min(maxRequested, textLimit));
return { minChars, maxChars, breakPreference: "newline" };
}
const maxRequested = Math.max(1, Math.floor(chunkCfg?.maxChars ?? DEFAULT_BLOCK_STREAM_MAX));
const maxChars = Math.max(1, Math.min(maxRequested, textLimit));
const minFallback = DEFAULT_BLOCK_STREAM_MIN;
@@ -91,6 +102,13 @@ export function resolveBlockStreamingCoalescing(
},
): BlockStreamingCoalescing | undefined {
const providerKey = normalizeChunkProvider(provider);
// BlueBubbles-only: when chunkMode is "newline", disable coalescing to send each line immediately
const channelChunkMode = resolveChunkMode(cfg, providerKey, accountId);
if (channelChunkMode === "newline") {
return undefined;
}
const providerId = providerKey ? normalizeChannelId(providerKey) : null;
const providerChunkLimit = providerId
? getChannelDock(providerId)?.outbound?.textChunkLimit