feat: improve outbound message chunking with code-block-aware splitting

- Increase max message length from 4000 to 8000 chars
- Add splitAtBoundary: paragraph > newline > space priority, never split
  inside fenced code blocks (move split to before opening fence)
- Add sendLongText: sends multi-chunk long messages sequentially
- Update PatchableTextStream.flush to use splitAtBoundary
- Add unit tests (6) for splitting edge cases
This commit is contained in:
2026-07-08 16:57:53 +08:00
parent 4736610cf3
commit bef10149a9
4 changed files with 196 additions and 10 deletions
+13
View File
@@ -9,6 +9,7 @@ import * as lark from "@larksuiteoapi/node-sdk";
import { readFile, writeFile, mkdir } from "node:fs/promises";
import { dirname } from "node:path";
import type { FastifyBaseLogger } from "fastify";
import { DEFAULT_MAX_MESSAGE_LENGTH, splitAtBoundary } from "./textStream.js";
export interface FeishuConfig {
readonly appId: string;
@@ -157,6 +158,18 @@ export async function sendTextMessage(rt: FeishuRuntime, chatId: string, text: s
}
}
/** Send long text as multiple Feishu messages. Returns the last successful message_id. */
export async function sendLongText(rt: FeishuRuntime, chatId: string, text: string): Promise<string | null> {
let lastMessageId: string | null = null;
for (const chunk of splitAtBoundary(text, DEFAULT_MAX_MESSAGE_LENGTH)) {
const messageId = await sendTextMessage(rt, chatId, chunk);
if (messageId !== null) {
lastMessageId = messageId;
}
}
return lastMessageId;
}
/** Send a plain text message (fire-and-forget). */
export async function sendText(rt: FeishuRuntime, chatId: string, text: string): Promise<void> {
await sendTextMessage(rt, chatId, text);