@tritard/waterbrother 0.16.144 → 0.16.146

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/discord.js +56 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.16.144",
3
+ "version": "0.16.146",
4
4
  "description": "Waterbrother: bring-your-own-model coding CLI with local tools, sessions, operator modes, and approval controls",
5
5
  "type": "module",
6
6
  "bin": {
package/src/discord.js CHANGED
@@ -36,6 +36,7 @@ const DISCORD_BRIDGE_TIMEOUT_MS = 5 * 60 * 1000;
36
36
  const DISCORD_BRIDGE_POLL_MS = 250;
37
37
  const DISCORD_CONTINUATION_TTL_MS = 15 * 60 * 1000;
38
38
  const DISCORD_COMMAND_VERSION = 1;
39
+ const DISCORD_MESSAGE_LIMIT = 2000;
39
40
 
40
41
  const INTENT_BITS = {
41
42
  GUILDS: 1 << 0,
@@ -337,13 +338,39 @@ async function fetchGatewayInfo(runtime) {
337
338
  return discordFetch(runtime, "/gateway/bot", { method: "GET" });
338
339
  }
339
340
 
341
+ function splitDiscordContent(content = "", limit = DISCORD_MESSAGE_LIMIT) {
342
+ const value = String(content || "").trim();
343
+ if (!value) return [];
344
+ if (value.length <= limit) return [value];
345
+ const chunks = [];
346
+ let remaining = value;
347
+ while (remaining.length > limit) {
348
+ let cut = remaining.lastIndexOf("\n", limit);
349
+ if (cut <= 0 || cut < Math.floor(limit * 0.5)) {
350
+ cut = remaining.lastIndexOf(" ", limit);
351
+ }
352
+ if (cut <= 0 || cut < Math.floor(limit * 0.5)) {
353
+ cut = limit;
354
+ }
355
+ const chunk = remaining.slice(0, cut).trim();
356
+ if (chunk) chunks.push(chunk);
357
+ remaining = remaining.slice(cut).trim();
358
+ }
359
+ if (remaining) chunks.push(remaining);
360
+ return chunks.length ? chunks : [value.slice(0, limit)];
361
+ }
362
+
340
363
  async function sendChannelMessage(runtime, channelId, content) {
341
- const text = String(content || "").trim();
342
- if (!channelId || !text) return null;
343
- return discordFetch(runtime, `/channels/${channelId}/messages`, {
344
- method: "POST",
345
- body: JSON.stringify({ content: text })
346
- });
364
+ const chunks = splitDiscordContent(content);
365
+ if (!channelId || !chunks.length) return null;
366
+ const replies = [];
367
+ for (const chunk of chunks) {
368
+ replies.push(await discordFetch(runtime, `/channels/${channelId}/messages`, {
369
+ method: "POST",
370
+ body: JSON.stringify({ content: chunk })
371
+ }));
372
+ }
373
+ return replies[0] || null;
347
374
  }
348
375
 
349
376
  async function createInteractionResponse(runtime, interaction, body) {
@@ -367,6 +394,27 @@ async function editInteractionResponse(runtime, interaction, content) {
367
394
  });
368
395
  }
369
396
 
397
+ async function sendInteractionFollowup(runtime, interaction, content) {
398
+ const text = String(content || "").trim();
399
+ if (!text) return null;
400
+ return discordFetch(runtime, `/webhooks/${runtime.applicationId}/${interaction.token}`, {
401
+ method: "POST",
402
+ body: JSON.stringify({ content: text })
403
+ });
404
+ }
405
+
406
+ async function sendInteractionReply(runtime, interaction, content) {
407
+ const chunks = splitDiscordContent(content);
408
+ if (!chunks.length) {
409
+ await editInteractionResponse(runtime, interaction, "(no content)");
410
+ return;
411
+ }
412
+ await editInteractionResponse(runtime, interaction, chunks[0]);
413
+ for (const chunk of chunks.slice(1)) {
414
+ await sendInteractionFollowup(runtime, interaction, chunk);
415
+ }
416
+ }
417
+
370
418
  function extractMentionContent(content, botUserId) {
371
419
  const raw = String(content || "");
372
420
  if (!botUserId) return raw.trim();
@@ -1339,11 +1387,11 @@ async function handleDiscordSlashInteraction(runtime, interaction, { log = () =>
1339
1387
  reply = await handleDiscordSessionCommand(runtime, state, message, command);
1340
1388
  }
1341
1389
  }
1342
- await editInteractionResponse(discord, interaction, reply || "Command completed.");
1390
+ await sendInteractionReply(discord, interaction, reply || "Command completed.");
1343
1391
  log(`discord: interaction reply in ${message.channel_id}`);
1344
1392
  } catch (error) {
1345
1393
  const text = error instanceof Error ? error.message : String(error);
1346
- await editInteractionResponse(discord, interaction, `Slash command failed: ${text}`);
1394
+ await sendInteractionReply(discord, interaction, `Slash command failed: ${text}`);
1347
1395
  throw error;
1348
1396
  }
1349
1397
  }