@herdctl/discord 0.0.1
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.
- package/dist/__tests__/auto-mode-handler.test.d.ts +2 -0
- package/dist/__tests__/auto-mode-handler.test.d.ts.map +1 -0
- package/dist/__tests__/auto-mode-handler.test.js +362 -0
- package/dist/__tests__/auto-mode-handler.test.js.map +1 -0
- package/dist/__tests__/discord-connector.test.d.ts +2 -0
- package/dist/__tests__/discord-connector.test.d.ts.map +1 -0
- package/dist/__tests__/discord-connector.test.js +958 -0
- package/dist/__tests__/discord-connector.test.js.map +1 -0
- package/dist/__tests__/error-handler.test.d.ts +2 -0
- package/dist/__tests__/error-handler.test.d.ts.map +1 -0
- package/dist/__tests__/error-handler.test.js +509 -0
- package/dist/__tests__/error-handler.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +152 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/logger.test.d.ts +2 -0
- package/dist/__tests__/logger.test.d.ts.map +1 -0
- package/dist/__tests__/logger.test.js +282 -0
- package/dist/__tests__/logger.test.js.map +1 -0
- package/dist/__tests__/mention-handler.test.d.ts +2 -0
- package/dist/__tests__/mention-handler.test.d.ts.map +1 -0
- package/dist/__tests__/mention-handler.test.js +547 -0
- package/dist/__tests__/mention-handler.test.js.map +1 -0
- package/dist/auto-mode-handler.d.ts +145 -0
- package/dist/auto-mode-handler.d.ts.map +1 -0
- package/dist/auto-mode-handler.js +211 -0
- package/dist/auto-mode-handler.js.map +1 -0
- package/dist/commands/__tests__/command-manager.test.d.ts +2 -0
- package/dist/commands/__tests__/command-manager.test.d.ts.map +1 -0
- package/dist/commands/__tests__/command-manager.test.js +307 -0
- package/dist/commands/__tests__/command-manager.test.js.map +1 -0
- package/dist/commands/__tests__/help.test.d.ts +2 -0
- package/dist/commands/__tests__/help.test.d.ts.map +1 -0
- package/dist/commands/__tests__/help.test.js +105 -0
- package/dist/commands/__tests__/help.test.js.map +1 -0
- package/dist/commands/__tests__/reset.test.d.ts +2 -0
- package/dist/commands/__tests__/reset.test.d.ts.map +1 -0
- package/dist/commands/__tests__/reset.test.js +140 -0
- package/dist/commands/__tests__/reset.test.js.map +1 -0
- package/dist/commands/__tests__/status.test.d.ts +2 -0
- package/dist/commands/__tests__/status.test.d.ts.map +1 -0
- package/dist/commands/__tests__/status.test.js +205 -0
- package/dist/commands/__tests__/status.test.js.map +1 -0
- package/dist/commands/command-manager.d.ts +66 -0
- package/dist/commands/command-manager.d.ts.map +1 -0
- package/dist/commands/command-manager.js +191 -0
- package/dist/commands/command-manager.js.map +1 -0
- package/dist/commands/help.d.ts +8 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +27 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/index.d.ts +12 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +13 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/reset.d.ts +9 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +28 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +102 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/types.d.ts +87 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +8 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/discord-connector.d.ts +154 -0
- package/dist/discord-connector.d.ts.map +1 -0
- package/dist/discord-connector.js +638 -0
- package/dist/discord-connector.js.map +1 -0
- package/dist/error-handler.d.ts +237 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +433 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/errors.d.ts +61 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +77 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +119 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +198 -0
- package/dist/logger.js.map +1 -0
- package/dist/mention-handler.d.ts +176 -0
- package/dist/mention-handler.d.ts.map +1 -0
- package/dist/mention-handler.js +236 -0
- package/dist/mention-handler.js.map +1 -0
- package/dist/session-manager/__tests__/errors.test.d.ts +2 -0
- package/dist/session-manager/__tests__/errors.test.d.ts.map +1 -0
- package/dist/session-manager/__tests__/errors.test.js +124 -0
- package/dist/session-manager/__tests__/errors.test.js.map +1 -0
- package/dist/session-manager/__tests__/session-manager.test.d.ts +2 -0
- package/dist/session-manager/__tests__/session-manager.test.d.ts.map +1 -0
- package/dist/session-manager/__tests__/session-manager.test.js +517 -0
- package/dist/session-manager/__tests__/session-manager.test.js.map +1 -0
- package/dist/session-manager/__tests__/types.test.d.ts +2 -0
- package/dist/session-manager/__tests__/types.test.d.ts.map +1 -0
- package/dist/session-manager/__tests__/types.test.js +169 -0
- package/dist/session-manager/__tests__/types.test.js.map +1 -0
- package/dist/session-manager/errors.d.ts +58 -0
- package/dist/session-manager/errors.d.ts.map +1 -0
- package/dist/session-manager/errors.js +70 -0
- package/dist/session-manager/errors.js.map +1 -0
- package/dist/session-manager/index.d.ts +11 -0
- package/dist/session-manager/index.d.ts.map +1 -0
- package/dist/session-manager/index.js +12 -0
- package/dist/session-manager/index.js.map +1 -0
- package/dist/session-manager/session-manager.d.ts +107 -0
- package/dist/session-manager/session-manager.d.ts.map +1 -0
- package/dist/session-manager/session-manager.js +347 -0
- package/dist/session-manager/session-manager.js.map +1 -0
- package/dist/session-manager/types.d.ts +167 -0
- package/dist/session-manager/types.d.ts.map +1 -0
- package/dist/session-manager/types.js +57 -0
- package/dist/session-manager/types.js.map +1 -0
- package/dist/types.d.ts +323 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/__tests__/formatting.test.d.ts +2 -0
- package/dist/utils/__tests__/formatting.test.d.ts.map +1 -0
- package/dist/utils/__tests__/formatting.test.js +571 -0
- package/dist/utils/__tests__/formatting.test.js.map +1 -0
- package/dist/utils/formatting.d.ts +211 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +305 -0
- package/dist/utils/formatting.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message formatting utilities for Discord
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for:
|
|
5
|
+
* - Splitting long messages to fit Discord's 2000 character limit
|
|
6
|
+
* - Maintaining message coherence when splitting (avoiding mid-sentence breaks)
|
|
7
|
+
* - Managing typing indicators during message processing
|
|
8
|
+
*/
|
|
9
|
+
import type { TextChannel, DMChannel, NewsChannel, ThreadChannel } from "discord.js";
|
|
10
|
+
/**
|
|
11
|
+
* Discord's maximum message length
|
|
12
|
+
*/
|
|
13
|
+
export declare const DISCORD_MAX_MESSAGE_LENGTH = 2000;
|
|
14
|
+
/**
|
|
15
|
+
* Default delay between sending split messages (in milliseconds)
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_MESSAGE_DELAY_MS = 500;
|
|
18
|
+
/**
|
|
19
|
+
* Minimum chunk size when splitting messages
|
|
20
|
+
* Prevents creating very small message fragments
|
|
21
|
+
*/
|
|
22
|
+
export declare const MIN_CHUNK_SIZE = 100;
|
|
23
|
+
/**
|
|
24
|
+
* Supported text-based channel types that can receive messages
|
|
25
|
+
*/
|
|
26
|
+
export type SendableChannel = TextChannel | DMChannel | NewsChannel | ThreadChannel;
|
|
27
|
+
/**
|
|
28
|
+
* Options for splitting messages
|
|
29
|
+
*/
|
|
30
|
+
export interface MessageSplitOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Maximum length for each message chunk (default: 2000)
|
|
33
|
+
*/
|
|
34
|
+
maxLength?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Whether to try to split at natural boundaries like sentences (default: true)
|
|
37
|
+
*/
|
|
38
|
+
preserveBoundaries?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Characters to use as split points, in order of preference (default: ['\n\n', '\n', '. ', '! ', '? ', ', ', ' '])
|
|
41
|
+
*/
|
|
42
|
+
splitPoints?: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Options for sending split messages
|
|
46
|
+
*/
|
|
47
|
+
export interface SendSplitOptions extends MessageSplitOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Delay between messages in milliseconds (default: 500)
|
|
50
|
+
*/
|
|
51
|
+
delayMs?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Result from splitting a message
|
|
55
|
+
*/
|
|
56
|
+
export interface SplitResult {
|
|
57
|
+
/**
|
|
58
|
+
* Array of message chunks
|
|
59
|
+
*/
|
|
60
|
+
chunks: string[];
|
|
61
|
+
/**
|
|
62
|
+
* Whether the message was split
|
|
63
|
+
*/
|
|
64
|
+
wasSplit: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Original message length
|
|
67
|
+
*/
|
|
68
|
+
originalLength: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Find the best split point within a text chunk
|
|
72
|
+
*
|
|
73
|
+
* @param text - Text to find split point in
|
|
74
|
+
* @param maxLength - Maximum length for the chunk
|
|
75
|
+
* @param splitPoints - Split points to search for, in order of preference
|
|
76
|
+
* @returns Index to split at, or maxLength if no good split point found
|
|
77
|
+
*/
|
|
78
|
+
export declare function findSplitPoint(text: string, maxLength: number, splitPoints?: string[]): number;
|
|
79
|
+
/**
|
|
80
|
+
* Split a message into chunks that fit Discord's message length limit
|
|
81
|
+
*
|
|
82
|
+
* @param content - Message content to split
|
|
83
|
+
* @param options - Split options
|
|
84
|
+
* @returns Split result with chunks array
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const result = splitMessage(longText);
|
|
89
|
+
* for (const chunk of result.chunks) {
|
|
90
|
+
* await channel.send(chunk);
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function splitMessage(content: string, options?: MessageSplitOptions): SplitResult;
|
|
95
|
+
/**
|
|
96
|
+
* Check if a message needs to be split
|
|
97
|
+
*
|
|
98
|
+
* @param content - Message content to check
|
|
99
|
+
* @param maxLength - Maximum message length (default: 2000)
|
|
100
|
+
* @returns true if the message exceeds the max length
|
|
101
|
+
*/
|
|
102
|
+
export declare function needsSplit(content: string, maxLength?: number): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Controller for managing a typing indicator loop
|
|
105
|
+
*/
|
|
106
|
+
export interface TypingController {
|
|
107
|
+
/**
|
|
108
|
+
* Stop the typing indicator
|
|
109
|
+
*/
|
|
110
|
+
stop(): void;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the typing indicator is currently active
|
|
113
|
+
*/
|
|
114
|
+
readonly isActive: boolean;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Start a typing indicator that refreshes automatically
|
|
118
|
+
*
|
|
119
|
+
* Discord typing indicators expire after ~10 seconds, so this function
|
|
120
|
+
* sets up an interval to keep refreshing the typing status until stopped.
|
|
121
|
+
*
|
|
122
|
+
* @param channel - Channel to show typing indicator in
|
|
123
|
+
* @param refreshInterval - How often to refresh (default: 5000ms)
|
|
124
|
+
* @returns Controller to stop the typing indicator
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const typing = startTypingIndicator(channel);
|
|
129
|
+
* try {
|
|
130
|
+
* const response = await processMessage(prompt);
|
|
131
|
+
* await channel.send(response);
|
|
132
|
+
* } finally {
|
|
133
|
+
* typing.stop();
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export declare function startTypingIndicator(channel: SendableChannel, refreshInterval?: number): TypingController;
|
|
138
|
+
/**
|
|
139
|
+
* Send a message, automatically splitting if needed
|
|
140
|
+
*
|
|
141
|
+
* @param channel - Channel to send the message to
|
|
142
|
+
* @param content - Message content to send
|
|
143
|
+
* @param options - Send options including split and delay settings
|
|
144
|
+
* @returns Array of message IDs for sent messages
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const messageIds = await sendSplitMessage(channel, longResponse, {
|
|
149
|
+
* delayMs: 500,
|
|
150
|
+
* preserveBoundaries: true,
|
|
151
|
+
* });
|
|
152
|
+
* console.log(`Sent ${messageIds.length} messages`);
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export declare function sendSplitMessage(channel: SendableChannel, content: string, options?: SendSplitOptions): Promise<string[]>;
|
|
156
|
+
/**
|
|
157
|
+
* Send a message with typing indicator
|
|
158
|
+
*
|
|
159
|
+
* Shows a typing indicator, processes the content, then sends the response.
|
|
160
|
+
* Automatically splits long messages.
|
|
161
|
+
*
|
|
162
|
+
* @param channel - Channel to send the message to
|
|
163
|
+
* @param contentProvider - Async function that generates the message content
|
|
164
|
+
* @param options - Send options
|
|
165
|
+
* @returns Array of message IDs for sent messages
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* const messageIds = await sendWithTyping(channel, async () => {
|
|
170
|
+
* return await generateResponse(prompt);
|
|
171
|
+
* });
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
export declare function sendWithTyping(channel: SendableChannel, contentProvider: () => Promise<string>, options?: SendSplitOptions): Promise<string[]>;
|
|
175
|
+
/**
|
|
176
|
+
* Truncate a message to fit within the max length, adding an ellipsis
|
|
177
|
+
*
|
|
178
|
+
* @param content - Message content to truncate
|
|
179
|
+
* @param maxLength - Maximum length (default: 2000)
|
|
180
|
+
* @param ellipsis - Ellipsis to append (default: '...')
|
|
181
|
+
* @returns Truncated message
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* const short = truncateMessage(longText, 100);
|
|
186
|
+
* // Returns: "This is a very long text that has been trun..."
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
export declare function truncateMessage(content: string, maxLength?: number, ellipsis?: string): string;
|
|
190
|
+
/**
|
|
191
|
+
* Format code as a Discord code block
|
|
192
|
+
*
|
|
193
|
+
* @param code - Code to format
|
|
194
|
+
* @param language - Optional language for syntax highlighting
|
|
195
|
+
* @returns Formatted code block
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* const formatted = formatCodeBlock('const x = 1;', 'typescript');
|
|
200
|
+
* // Returns: "```typescript\nconst x = 1;\n```"
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
export declare function formatCodeBlock(code: string, language?: string): string;
|
|
204
|
+
/**
|
|
205
|
+
* Escape Discord markdown characters in text
|
|
206
|
+
*
|
|
207
|
+
* @param text - Text to escape
|
|
208
|
+
* @returns Text with markdown characters escaped
|
|
209
|
+
*/
|
|
210
|
+
export declare function escapeMarkdown(text: string): string;
|
|
211
|
+
//# sourceMappingURL=formatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,aAAa,EACd,MAAM,YAAY,CAAC;AAMpB;;GAEG;AACH,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAMlC;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,SAAS,GACT,WAAW,GACX,aAAa,CAAC;AAElB;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAaD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAM,EAAyB,GAC3C,MAAM,CA4BR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAChC,WAAW,CAoDb;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAmC,GAC7C,OAAO,CAET;AAMD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,eAAe,EACxB,eAAe,GAAE,MAAa,GAC7B,gBAAgB,CA8BlB;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,EAAE,CAAC,CAoBnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,eAAe,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EACtC,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,EAAE,CAAC,CASnB;AAeD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAmC,EAC9C,QAAQ,GAAE,MAAc,GACvB,MAAM,CAOR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAGvE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message formatting utilities for Discord
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for:
|
|
5
|
+
* - Splitting long messages to fit Discord's 2000 character limit
|
|
6
|
+
* - Maintaining message coherence when splitting (avoiding mid-sentence breaks)
|
|
7
|
+
* - Managing typing indicators during message processing
|
|
8
|
+
*/
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Constants
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Discord's maximum message length
|
|
14
|
+
*/
|
|
15
|
+
export const DISCORD_MAX_MESSAGE_LENGTH = 2000;
|
|
16
|
+
/**
|
|
17
|
+
* Default delay between sending split messages (in milliseconds)
|
|
18
|
+
*/
|
|
19
|
+
export const DEFAULT_MESSAGE_DELAY_MS = 500;
|
|
20
|
+
/**
|
|
21
|
+
* Minimum chunk size when splitting messages
|
|
22
|
+
* Prevents creating very small message fragments
|
|
23
|
+
*/
|
|
24
|
+
export const MIN_CHUNK_SIZE = 100;
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// Message Splitting
|
|
27
|
+
// =============================================================================
|
|
28
|
+
/**
|
|
29
|
+
* Default split points in order of preference
|
|
30
|
+
*
|
|
31
|
+
* We prefer to split at paragraph breaks, then sentences, then clauses, then words
|
|
32
|
+
*/
|
|
33
|
+
const DEFAULT_SPLIT_POINTS = ["\n\n", "\n", ". ", "! ", "? ", ", ", " "];
|
|
34
|
+
/**
|
|
35
|
+
* Find the best split point within a text chunk
|
|
36
|
+
*
|
|
37
|
+
* @param text - Text to find split point in
|
|
38
|
+
* @param maxLength - Maximum length for the chunk
|
|
39
|
+
* @param splitPoints - Split points to search for, in order of preference
|
|
40
|
+
* @returns Index to split at, or maxLength if no good split point found
|
|
41
|
+
*/
|
|
42
|
+
export function findSplitPoint(text, maxLength, splitPoints = DEFAULT_SPLIT_POINTS) {
|
|
43
|
+
// If text fits, no split needed
|
|
44
|
+
if (text.length <= maxLength) {
|
|
45
|
+
return text.length;
|
|
46
|
+
}
|
|
47
|
+
// Try each split point in order of preference
|
|
48
|
+
for (const splitPoint of splitPoints) {
|
|
49
|
+
// Search backwards from maxLength to find the last occurrence of this split point
|
|
50
|
+
const searchText = text.slice(0, maxLength);
|
|
51
|
+
const lastIndex = searchText.lastIndexOf(splitPoint);
|
|
52
|
+
// If found and results in a reasonable chunk size
|
|
53
|
+
if (lastIndex > MIN_CHUNK_SIZE) {
|
|
54
|
+
// Include the split point in the first chunk (e.g., keep the period with the sentence)
|
|
55
|
+
return lastIndex + splitPoint.length;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// No good split point found - fall back to hard split at maxLength
|
|
59
|
+
// But try to avoid splitting in the middle of a word
|
|
60
|
+
const hardSplitIndex = text.lastIndexOf(" ", maxLength);
|
|
61
|
+
if (hardSplitIndex > MIN_CHUNK_SIZE) {
|
|
62
|
+
return hardSplitIndex + 1; // Include the space in the first chunk
|
|
63
|
+
}
|
|
64
|
+
// Last resort: hard split at maxLength
|
|
65
|
+
return maxLength;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Split a message into chunks that fit Discord's message length limit
|
|
69
|
+
*
|
|
70
|
+
* @param content - Message content to split
|
|
71
|
+
* @param options - Split options
|
|
72
|
+
* @returns Split result with chunks array
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const result = splitMessage(longText);
|
|
77
|
+
* for (const chunk of result.chunks) {
|
|
78
|
+
* await channel.send(chunk);
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function splitMessage(content, options = {}) {
|
|
83
|
+
const { maxLength = DISCORD_MAX_MESSAGE_LENGTH, preserveBoundaries = true, splitPoints = DEFAULT_SPLIT_POINTS, } = options;
|
|
84
|
+
const originalLength = content.length;
|
|
85
|
+
// If content fits in one message, return as-is
|
|
86
|
+
if (content.length <= maxLength) {
|
|
87
|
+
return {
|
|
88
|
+
chunks: [content],
|
|
89
|
+
wasSplit: false,
|
|
90
|
+
originalLength,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const chunks = [];
|
|
94
|
+
let remaining = content;
|
|
95
|
+
while (remaining.length > 0) {
|
|
96
|
+
if (remaining.length <= maxLength) {
|
|
97
|
+
// Remaining text fits in one message
|
|
98
|
+
chunks.push(remaining.trim());
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
// Find the best split point
|
|
102
|
+
let splitIndex;
|
|
103
|
+
if (preserveBoundaries) {
|
|
104
|
+
splitIndex = findSplitPoint(remaining, maxLength, splitPoints);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Simple split at maxLength
|
|
108
|
+
splitIndex = maxLength;
|
|
109
|
+
}
|
|
110
|
+
// Extract the chunk and trim
|
|
111
|
+
const chunk = remaining.slice(0, splitIndex).trim();
|
|
112
|
+
if (chunk.length > 0) {
|
|
113
|
+
chunks.push(chunk);
|
|
114
|
+
}
|
|
115
|
+
// Update remaining text
|
|
116
|
+
remaining = remaining.slice(splitIndex).trim();
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
chunks,
|
|
120
|
+
wasSplit: chunks.length > 1,
|
|
121
|
+
originalLength,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if a message needs to be split
|
|
126
|
+
*
|
|
127
|
+
* @param content - Message content to check
|
|
128
|
+
* @param maxLength - Maximum message length (default: 2000)
|
|
129
|
+
* @returns true if the message exceeds the max length
|
|
130
|
+
*/
|
|
131
|
+
export function needsSplit(content, maxLength = DISCORD_MAX_MESSAGE_LENGTH) {
|
|
132
|
+
return content.length > maxLength;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Start a typing indicator that refreshes automatically
|
|
136
|
+
*
|
|
137
|
+
* Discord typing indicators expire after ~10 seconds, so this function
|
|
138
|
+
* sets up an interval to keep refreshing the typing status until stopped.
|
|
139
|
+
*
|
|
140
|
+
* @param channel - Channel to show typing indicator in
|
|
141
|
+
* @param refreshInterval - How often to refresh (default: 5000ms)
|
|
142
|
+
* @returns Controller to stop the typing indicator
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const typing = startTypingIndicator(channel);
|
|
147
|
+
* try {
|
|
148
|
+
* const response = await processMessage(prompt);
|
|
149
|
+
* await channel.send(response);
|
|
150
|
+
* } finally {
|
|
151
|
+
* typing.stop();
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export function startTypingIndicator(channel, refreshInterval = 5000) {
|
|
156
|
+
let isActive = true;
|
|
157
|
+
let intervalId = null;
|
|
158
|
+
// Send initial typing indicator
|
|
159
|
+
channel.sendTyping().catch(() => {
|
|
160
|
+
// Ignore errors - typing indicator is not critical
|
|
161
|
+
});
|
|
162
|
+
// Set up refresh interval
|
|
163
|
+
intervalId = setInterval(() => {
|
|
164
|
+
if (isActive) {
|
|
165
|
+
channel.sendTyping().catch(() => {
|
|
166
|
+
// Ignore errors
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}, refreshInterval);
|
|
170
|
+
return {
|
|
171
|
+
stop() {
|
|
172
|
+
isActive = false;
|
|
173
|
+
if (intervalId !== null) {
|
|
174
|
+
clearInterval(intervalId);
|
|
175
|
+
intervalId = null;
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
get isActive() {
|
|
179
|
+
return isActive;
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// =============================================================================
|
|
184
|
+
// Combined Send Utilities
|
|
185
|
+
// =============================================================================
|
|
186
|
+
/**
|
|
187
|
+
* Send a message, automatically splitting if needed
|
|
188
|
+
*
|
|
189
|
+
* @param channel - Channel to send the message to
|
|
190
|
+
* @param content - Message content to send
|
|
191
|
+
* @param options - Send options including split and delay settings
|
|
192
|
+
* @returns Array of message IDs for sent messages
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const messageIds = await sendSplitMessage(channel, longResponse, {
|
|
197
|
+
* delayMs: 500,
|
|
198
|
+
* preserveBoundaries: true,
|
|
199
|
+
* });
|
|
200
|
+
* console.log(`Sent ${messageIds.length} messages`);
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
export async function sendSplitMessage(channel, content, options = {}) {
|
|
204
|
+
const { delayMs = DEFAULT_MESSAGE_DELAY_MS, ...splitOptions } = options;
|
|
205
|
+
const { chunks } = splitMessage(content, splitOptions);
|
|
206
|
+
const messageIds = [];
|
|
207
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
208
|
+
const chunk = chunks[i];
|
|
209
|
+
// Send the message
|
|
210
|
+
const message = await channel.send(chunk);
|
|
211
|
+
messageIds.push(message.id);
|
|
212
|
+
// Add delay between messages (except after the last one)
|
|
213
|
+
if (i < chunks.length - 1 && delayMs > 0) {
|
|
214
|
+
await sleep(delayMs);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return messageIds;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Send a message with typing indicator
|
|
221
|
+
*
|
|
222
|
+
* Shows a typing indicator, processes the content, then sends the response.
|
|
223
|
+
* Automatically splits long messages.
|
|
224
|
+
*
|
|
225
|
+
* @param channel - Channel to send the message to
|
|
226
|
+
* @param contentProvider - Async function that generates the message content
|
|
227
|
+
* @param options - Send options
|
|
228
|
+
* @returns Array of message IDs for sent messages
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const messageIds = await sendWithTyping(channel, async () => {
|
|
233
|
+
* return await generateResponse(prompt);
|
|
234
|
+
* });
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
export async function sendWithTyping(channel, contentProvider, options = {}) {
|
|
238
|
+
const typing = startTypingIndicator(channel);
|
|
239
|
+
try {
|
|
240
|
+
const content = await contentProvider();
|
|
241
|
+
return await sendSplitMessage(channel, content, options);
|
|
242
|
+
}
|
|
243
|
+
finally {
|
|
244
|
+
typing.stop();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// =============================================================================
|
|
248
|
+
// Utility Functions
|
|
249
|
+
// =============================================================================
|
|
250
|
+
/**
|
|
251
|
+
* Sleep for a specified duration
|
|
252
|
+
*
|
|
253
|
+
* @param ms - Duration in milliseconds
|
|
254
|
+
*/
|
|
255
|
+
function sleep(ms) {
|
|
256
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Truncate a message to fit within the max length, adding an ellipsis
|
|
260
|
+
*
|
|
261
|
+
* @param content - Message content to truncate
|
|
262
|
+
* @param maxLength - Maximum length (default: 2000)
|
|
263
|
+
* @param ellipsis - Ellipsis to append (default: '...')
|
|
264
|
+
* @returns Truncated message
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```typescript
|
|
268
|
+
* const short = truncateMessage(longText, 100);
|
|
269
|
+
* // Returns: "This is a very long text that has been trun..."
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
export function truncateMessage(content, maxLength = DISCORD_MAX_MESSAGE_LENGTH, ellipsis = "...") {
|
|
273
|
+
if (content.length <= maxLength) {
|
|
274
|
+
return content;
|
|
275
|
+
}
|
|
276
|
+
const truncatedLength = maxLength - ellipsis.length;
|
|
277
|
+
return content.slice(0, truncatedLength) + ellipsis;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Format code as a Discord code block
|
|
281
|
+
*
|
|
282
|
+
* @param code - Code to format
|
|
283
|
+
* @param language - Optional language for syntax highlighting
|
|
284
|
+
* @returns Formatted code block
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```typescript
|
|
288
|
+
* const formatted = formatCodeBlock('const x = 1;', 'typescript');
|
|
289
|
+
* // Returns: "```typescript\nconst x = 1;\n```"
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export function formatCodeBlock(code, language) {
|
|
293
|
+
const langTag = language ?? "";
|
|
294
|
+
return `\`\`\`${langTag}\n${code}\n\`\`\``;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Escape Discord markdown characters in text
|
|
298
|
+
*
|
|
299
|
+
* @param text - Text to escape
|
|
300
|
+
* @returns Text with markdown characters escaped
|
|
301
|
+
*/
|
|
302
|
+
export function escapeMarkdown(text) {
|
|
303
|
+
return text.replace(/([*_~`|\\])/g, "\\$1");
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=formatting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility modules for the Discord connector
|
|
3
|
+
*/
|
|
4
|
+
export { DISCORD_MAX_MESSAGE_LENGTH, DEFAULT_MESSAGE_DELAY_MS, MIN_CHUNK_SIZE, findSplitPoint, splitMessage, needsSplit, startTypingIndicator, sendSplitMessage, sendWithTyping, truncateMessage, formatCodeBlock, escapeMarkdown, type SendableChannel, type MessageSplitOptions, type SendSplitOptions, type SplitResult, type TypingController, } from "./formatting.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAEL,0BAA0B,EAC1B,wBAAwB,EACxB,cAAc,EAEd,cAAc,EACd,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,EAEd,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility modules for the Discord connector
|
|
3
|
+
*/
|
|
4
|
+
export {
|
|
5
|
+
// Constants
|
|
6
|
+
DISCORD_MAX_MESSAGE_LENGTH, DEFAULT_MESSAGE_DELAY_MS, MIN_CHUNK_SIZE,
|
|
7
|
+
// Functions
|
|
8
|
+
findSplitPoint, splitMessage, needsSplit, startTypingIndicator, sendSplitMessage, sendWithTyping, truncateMessage, formatCodeBlock, escapeMarkdown, } from "./formatting.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO;AACL,YAAY;AACZ,0BAA0B,EAC1B,wBAAwB,EACxB,cAAc;AACd,YAAY;AACZ,cAAc,EACd,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,EACf,cAAc,GAOf,MAAM,iBAAiB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@herdctl/discord",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Discord connector for herdctl fleet management",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"dev": "tsc --watch",
|
|
15
|
+
"typecheck": "tsc --noEmit",
|
|
16
|
+
"test": "vitest run --coverage"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@discordjs/rest": "^2.6.0",
|
|
20
|
+
"@herdctl/core": "workspace:*",
|
|
21
|
+
"discord.js": "^14.16.0",
|
|
22
|
+
"yaml": "^2.3.0",
|
|
23
|
+
"zod": "^3.22.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@vitest/coverage-v8": "^4.0.17",
|
|
27
|
+
"typescript": "^5",
|
|
28
|
+
"vitest": "^4.0.17"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://herdctl.dev",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/edspencer/herdctl"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"claude",
|
|
37
|
+
"agent",
|
|
38
|
+
"fleet",
|
|
39
|
+
"orchestration",
|
|
40
|
+
"anthropic",
|
|
41
|
+
"discord"
|
|
42
|
+
],
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
}
|
|
49
|
+
}
|