fix(discord): chunk replies over 2000 chars instead of truncating#2812
fix(discord): chunk replies over 2000 chars instead of truncating#2812axnjxn415 wants to merge 2 commits into
Conversation
The Chat SDK bridge ships a splitForLimit chunker that splits long replies across multiple messages, but it only runs when the adapter sets maxTextLength. The Discord adapter never set it, so any reply over Discord's 2000-char hard cap was silently truncated with an ellipsis by @chat-adapter/discord instead of being chunked. Set maxTextLength: 2000 so long Discord replies chunk across multiple messages. Surfaces most often with verbose models that emit long single messages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Maintainer pass looks good overall — the Discord fix is scoped and the bridge already has the right chunking path. I verified locally in a disposable checkout: npx vitest run src/channels/chat-sdk-bridge.test.ts src/channels/discord-registration.test.tsResult with the added regression below: 2 test files passed, 9 tests passed. Before merge, please add this small regression test so the diff --git a/src/channels/chat-sdk-bridge.test.ts b/src/channels/chat-sdk-bridge.test.ts
index 7e3c4ff..164a3f2 100644
--- a/src/channels/chat-sdk-bridge.test.ts
+++ b/src/channels/chat-sdk-bridge.test.ts
@@ -77,4 +77,27 @@ describe('createChatSdkBridge', () => {
});
expect(typeof bridge.subscribe).toBe('function');
});
+
+ it('splits outbound text when maxTextLength is set', async () => {
+ const posted: string[] = [];
+ const bridge = createChatSdkBridge({
+ adapter: stubAdapter({
+ postMessage: async (_threadId: string, message: { markdown?: string }) => {
+ posted.push(message.markdown ?? '');
+ return { id: `msg-${posted.length}` };
+ },
+ }),
+ supportsThreads: true,
+ maxTextLength: 10,
+ });
+
+ const id = await bridge.deliver('stub:channel', null, {
+ content: { text: 'alpha bravo charlie delta' },
+ });
+
+ expect(id).toBe('msg-1');
+ expect(posted.length).toBeGreaterThan(1);
+ expect(posted.every((chunk) => chunk.length <= 10)).toBe(true);
+ expect(posted.join(' ')).toBe('alpha bravo charlie delta');
+ });
});I tried pushing this directly because |
|
Reviewed this and opened a replacement with regression coverage: #2816 Delta: same Discord maxTextLength=2000 fix, plus a registration test proving the Discord adapter passes the limit to createChatSdkBridge. |
…egress Adds src/channels/discord.test.ts — stubs the factory's collaborators and asserts the Discord adapter passes maxTextLength: 2000 into createChatSdkBridge. Verified it fails if the line is removed. Addresses review feedback on nanocoai#2812. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…egress Adds src/channels/discord.test.ts — stubs the factory's collaborators and asserts the Discord adapter passes maxTextLength: 2000 into createChatSdkBridge. Verified it fails if the line is removed. Addresses review feedback on nanocoai#2812. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9709d52 to
ebee085
Compare
|
Thanks for the review. Added a regression test ( I kept it as a focused adapter test next to the existing This PR is the original fix for the truncation bug; #2816 duplicates the same one-line change, so this one can land standalone. |
What
The Chat SDK bridge ships a
splitForLimitchunker (src/channels/chat-sdk-bridge.ts) that splits a reply longer thanmaxTextLengthacross multiple platform messages. It only runs when the adapter passesmaxTextLengthintocreateChatSdkBridge. The Discord adapter never set it, so any reply over Discord's 2000-char hard cap was silently truncated with an ellipsis by@chat-adapter/discordinstead of being chunked.This sets
maxTextLength: 2000on the Discord adapter so long replies chunk across multiple messages.Why
Whenever an agent emits a single reply over 2000 chars, the message is cut off mid-sentence with
…and the remainder is lost — no error, no log. It shows up more often with more verbose models that tend to write longer single messages. Observed in production.Note — same omission in other adapters
Several other adapters call
createChatSdkBridgewithoutmaxTextLengthand have the same latent truncation:gchat,github,imessage,linear,matrix,resend,slack,teams,webex,whatsapp-cloud. Onlydiscord(after this PR) andtelegramset it.I scoped this PR to Discord — the confirmed, production-verified case — rather than guess each platform's character limit. Flagging it here in case you'd like to extend the fix across the fleet.
Testing
Verified across three production installs: with
maxTextLengthset,splitForLimitengages and replies over the cap arrive as multiple messages instead of one truncated message. No behavior change for replies under the cap.