@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,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mention handler for Discord bot interactions
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for:
|
|
5
|
+
* - Detecting bot mentions in messages
|
|
6
|
+
* - Stripping mentions from prompt text
|
|
7
|
+
* - Building conversation context from message history
|
|
8
|
+
*/
|
|
9
|
+
import type { Message, Collection, Snowflake, TextChannel, DMChannel, NewsChannel, ThreadChannel } from "discord.js";
|
|
10
|
+
/**
|
|
11
|
+
* Supported text-based channel types for message fetching
|
|
12
|
+
*/
|
|
13
|
+
export type TextBasedChannel = TextChannel | DMChannel | NewsChannel | ThreadChannel;
|
|
14
|
+
/**
|
|
15
|
+
* A processed message for context building
|
|
16
|
+
*/
|
|
17
|
+
export interface ContextMessage {
|
|
18
|
+
/** Discord user ID of the message author */
|
|
19
|
+
authorId: string;
|
|
20
|
+
/** Display name or username of the message author */
|
|
21
|
+
authorName: string;
|
|
22
|
+
/** Whether the author is a bot */
|
|
23
|
+
isBot: boolean;
|
|
24
|
+
/** Whether this is the bot's own message */
|
|
25
|
+
isSelf: boolean;
|
|
26
|
+
/** Message content with any bot mentions stripped */
|
|
27
|
+
content: string;
|
|
28
|
+
/** ISO timestamp of when the message was created */
|
|
29
|
+
timestamp: string;
|
|
30
|
+
/** The original message ID */
|
|
31
|
+
messageId: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Options for building conversation context
|
|
35
|
+
*/
|
|
36
|
+
export interface ContextBuildOptions {
|
|
37
|
+
/** Maximum number of messages to include (default: 10) */
|
|
38
|
+
maxMessages?: number;
|
|
39
|
+
/** Whether to include bot messages in context (default: true) */
|
|
40
|
+
includeBotMessages?: boolean;
|
|
41
|
+
/** Whether to prioritize user messages over bot messages (default: true) */
|
|
42
|
+
prioritizeUserMessages?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Result of context building
|
|
46
|
+
*/
|
|
47
|
+
export interface ConversationContext {
|
|
48
|
+
/** Processed messages in chronological order (oldest first) */
|
|
49
|
+
messages: ContextMessage[];
|
|
50
|
+
/** The triggering message with mention stripped */
|
|
51
|
+
prompt: string;
|
|
52
|
+
/** Whether the bot was mentioned in the triggering message */
|
|
53
|
+
wasMentioned: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if a message mentions a specific bot user
|
|
57
|
+
*
|
|
58
|
+
* @param message - Discord message to check
|
|
59
|
+
* @param botUserId - The bot's user ID
|
|
60
|
+
* @returns true if the bot is mentioned, false otherwise
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* if (isBotMentioned(message, client.user.id)) {
|
|
65
|
+
* // Handle the mention
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function isBotMentioned(message: Message, botUserId: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Check if a message should be processed based on channel mode
|
|
72
|
+
*
|
|
73
|
+
* @param message - Discord message to check
|
|
74
|
+
* @param botUserId - The bot's user ID
|
|
75
|
+
* @param mode - Channel mode ('mention' or 'auto')
|
|
76
|
+
* @returns true if the message should be processed, false otherwise
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* if (shouldProcessMessage(message, client.user.id, 'mention')) {
|
|
81
|
+
* // Bot was mentioned, process the message
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function shouldProcessMessage(message: Message, botUserId: string, mode: "mention" | "auto"): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Strip bot mention from message content
|
|
88
|
+
*
|
|
89
|
+
* Removes the bot mention (e.g., <@123456789>) from the message content
|
|
90
|
+
* and trims any excess whitespace.
|
|
91
|
+
*
|
|
92
|
+
* @param content - Message content to process
|
|
93
|
+
* @param botUserId - The bot's user ID
|
|
94
|
+
* @returns Content with the bot mention removed
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const prompt = stripBotMention("<@123> help me with this", "123");
|
|
99
|
+
* // Returns: "help me with this"
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare function stripBotMention(content: string, botUserId: string): string;
|
|
103
|
+
/**
|
|
104
|
+
* Strip all bot mentions from message content
|
|
105
|
+
*
|
|
106
|
+
* Removes all user mentions from the message content. Useful for
|
|
107
|
+
* cleaning context messages.
|
|
108
|
+
*
|
|
109
|
+
* @param content - Message content to process
|
|
110
|
+
* @param botUserId - The bot's user ID (optional, if provided only strips this bot)
|
|
111
|
+
* @returns Content with mentions removed
|
|
112
|
+
*/
|
|
113
|
+
export declare function stripMentions(content: string, botUserId?: string): string;
|
|
114
|
+
/**
|
|
115
|
+
* Process a Discord message into a context message
|
|
116
|
+
*
|
|
117
|
+
* @param message - Discord message to process
|
|
118
|
+
* @param botUserId - The bot's user ID
|
|
119
|
+
* @returns Processed context message
|
|
120
|
+
*/
|
|
121
|
+
export declare function processMessage(message: Message, botUserId: string): ContextMessage;
|
|
122
|
+
/**
|
|
123
|
+
* Fetch recent message history from a channel
|
|
124
|
+
*
|
|
125
|
+
* @param channel - Text-based channel to fetch from
|
|
126
|
+
* @param beforeMessageId - Fetch messages before this message ID
|
|
127
|
+
* @param limit - Maximum number of messages to fetch
|
|
128
|
+
* @returns Collection of messages
|
|
129
|
+
*/
|
|
130
|
+
export declare function fetchMessageHistory(channel: TextBasedChannel, beforeMessageId: string, limit: number): Promise<Collection<Snowflake, Message>>;
|
|
131
|
+
/**
|
|
132
|
+
* Build conversation context from message history
|
|
133
|
+
*
|
|
134
|
+
* Fetches recent messages from the channel and processes them into
|
|
135
|
+
* a conversation context suitable for sending to Claude.
|
|
136
|
+
*
|
|
137
|
+
* @param triggerMessage - The message that triggered the bot
|
|
138
|
+
* @param channel - The channel to fetch history from
|
|
139
|
+
* @param botUserId - The bot's user ID
|
|
140
|
+
* @param options - Context building options
|
|
141
|
+
* @returns Conversation context with processed messages
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* const context = await buildConversationContext(
|
|
146
|
+
* message,
|
|
147
|
+
* message.channel,
|
|
148
|
+
* client.user.id,
|
|
149
|
+
* { maxMessages: 10, prioritizeUserMessages: true }
|
|
150
|
+
* );
|
|
151
|
+
*
|
|
152
|
+
* // Use context.prompt as the main prompt
|
|
153
|
+
* // Use context.messages for conversation history
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
export declare function buildConversationContext(triggerMessage: Message, channel: TextBasedChannel, botUserId: string, options?: ContextBuildOptions): Promise<ConversationContext>;
|
|
157
|
+
/**
|
|
158
|
+
* Format conversation context as a string for Claude
|
|
159
|
+
*
|
|
160
|
+
* Creates a formatted string representation of the conversation context
|
|
161
|
+
* suitable for including in a prompt to Claude.
|
|
162
|
+
*
|
|
163
|
+
* @param context - The conversation context to format
|
|
164
|
+
* @returns Formatted string representation
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* const formatted = formatContextForPrompt(context);
|
|
169
|
+
* // Returns:
|
|
170
|
+
* // [User123 at 2024-01-20T10:00:00Z]: How do I use this feature?
|
|
171
|
+
* // [BotName at 2024-01-20T10:00:30Z]: Here's how you can...
|
|
172
|
+
* // [User123 at 2024-01-20T10:01:00Z]: Thanks, but what about...
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export declare function formatContextForPrompt(context: ConversationContext): string;
|
|
176
|
+
//# sourceMappingURL=mention-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-handler.d.ts","sourceRoot":"","sources":["../src/mention-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMrH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,4CAA4C;IAC5C,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4EAA4E;IAC5E,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,YAAY,EAAE,OAAO,CAAC;CACvB;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAG3E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,SAAS,GAAG,MAAM,GACvB,OAAO,CAaT;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAMzE;AAMD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,cAAc,CAUhB;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,gBAAgB,EACzB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAKzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,mBAAmB,CAAC,CAoE9B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAW3E"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mention handler for Discord bot interactions
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for:
|
|
5
|
+
* - Detecting bot mentions in messages
|
|
6
|
+
* - Stripping mentions from prompt text
|
|
7
|
+
* - Building conversation context from message history
|
|
8
|
+
*/
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Mention Detection
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Check if a message mentions a specific bot user
|
|
14
|
+
*
|
|
15
|
+
* @param message - Discord message to check
|
|
16
|
+
* @param botUserId - The bot's user ID
|
|
17
|
+
* @returns true if the bot is mentioned, false otherwise
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* if (isBotMentioned(message, client.user.id)) {
|
|
22
|
+
* // Handle the mention
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function isBotMentioned(message, botUserId) {
|
|
27
|
+
// Check if the bot is directly mentioned
|
|
28
|
+
return message.mentions.users.has(botUserId);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if a message should be processed based on channel mode
|
|
32
|
+
*
|
|
33
|
+
* @param message - Discord message to check
|
|
34
|
+
* @param botUserId - The bot's user ID
|
|
35
|
+
* @param mode - Channel mode ('mention' or 'auto')
|
|
36
|
+
* @returns true if the message should be processed, false otherwise
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* if (shouldProcessMessage(message, client.user.id, 'mention')) {
|
|
41
|
+
* // Bot was mentioned, process the message
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function shouldProcessMessage(message, botUserId, mode) {
|
|
46
|
+
// Never process messages from bots (including self)
|
|
47
|
+
if (message.author.bot) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
// In 'auto' mode, process all non-bot messages
|
|
51
|
+
if (mode === "auto") {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
// In 'mention' mode, only process if bot is mentioned
|
|
55
|
+
return isBotMentioned(message, botUserId);
|
|
56
|
+
}
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// Mention Stripping
|
|
59
|
+
// =============================================================================
|
|
60
|
+
/**
|
|
61
|
+
* Strip bot mention from message content
|
|
62
|
+
*
|
|
63
|
+
* Removes the bot mention (e.g., <@123456789>) from the message content
|
|
64
|
+
* and trims any excess whitespace.
|
|
65
|
+
*
|
|
66
|
+
* @param content - Message content to process
|
|
67
|
+
* @param botUserId - The bot's user ID
|
|
68
|
+
* @returns Content with the bot mention removed
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const prompt = stripBotMention("<@123> help me with this", "123");
|
|
73
|
+
* // Returns: "help me with this"
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export function stripBotMention(content, botUserId) {
|
|
77
|
+
// Match both regular mentions <@id> and nickname mentions <@!id>
|
|
78
|
+
const mentionRegex = new RegExp(`<@!?${botUserId}>`, "g");
|
|
79
|
+
return content.replace(mentionRegex, "").trim();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Strip all bot mentions from message content
|
|
83
|
+
*
|
|
84
|
+
* Removes all user mentions from the message content. Useful for
|
|
85
|
+
* cleaning context messages.
|
|
86
|
+
*
|
|
87
|
+
* @param content - Message content to process
|
|
88
|
+
* @param botUserId - The bot's user ID (optional, if provided only strips this bot)
|
|
89
|
+
* @returns Content with mentions removed
|
|
90
|
+
*/
|
|
91
|
+
export function stripMentions(content, botUserId) {
|
|
92
|
+
if (botUserId) {
|
|
93
|
+
return stripBotMention(content, botUserId);
|
|
94
|
+
}
|
|
95
|
+
// Strip all user mentions
|
|
96
|
+
return content.replace(/<@!?\d+>/g, "").trim();
|
|
97
|
+
}
|
|
98
|
+
// =============================================================================
|
|
99
|
+
// Context Building
|
|
100
|
+
// =============================================================================
|
|
101
|
+
/**
|
|
102
|
+
* Process a Discord message into a context message
|
|
103
|
+
*
|
|
104
|
+
* @param message - Discord message to process
|
|
105
|
+
* @param botUserId - The bot's user ID
|
|
106
|
+
* @returns Processed context message
|
|
107
|
+
*/
|
|
108
|
+
export function processMessage(message, botUserId) {
|
|
109
|
+
return {
|
|
110
|
+
authorId: message.author.id,
|
|
111
|
+
authorName: message.author.displayName ?? message.author.username,
|
|
112
|
+
isBot: message.author.bot,
|
|
113
|
+
isSelf: message.author.id === botUserId,
|
|
114
|
+
content: stripBotMention(message.content, botUserId),
|
|
115
|
+
timestamp: message.createdAt.toISOString(),
|
|
116
|
+
messageId: message.id,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Fetch recent message history from a channel
|
|
121
|
+
*
|
|
122
|
+
* @param channel - Text-based channel to fetch from
|
|
123
|
+
* @param beforeMessageId - Fetch messages before this message ID
|
|
124
|
+
* @param limit - Maximum number of messages to fetch
|
|
125
|
+
* @returns Collection of messages
|
|
126
|
+
*/
|
|
127
|
+
export async function fetchMessageHistory(channel, beforeMessageId, limit) {
|
|
128
|
+
return channel.messages.fetch({
|
|
129
|
+
before: beforeMessageId,
|
|
130
|
+
limit,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Build conversation context from message history
|
|
135
|
+
*
|
|
136
|
+
* Fetches recent messages from the channel and processes them into
|
|
137
|
+
* a conversation context suitable for sending to Claude.
|
|
138
|
+
*
|
|
139
|
+
* @param triggerMessage - The message that triggered the bot
|
|
140
|
+
* @param channel - The channel to fetch history from
|
|
141
|
+
* @param botUserId - The bot's user ID
|
|
142
|
+
* @param options - Context building options
|
|
143
|
+
* @returns Conversation context with processed messages
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* const context = await buildConversationContext(
|
|
148
|
+
* message,
|
|
149
|
+
* message.channel,
|
|
150
|
+
* client.user.id,
|
|
151
|
+
* { maxMessages: 10, prioritizeUserMessages: true }
|
|
152
|
+
* );
|
|
153
|
+
*
|
|
154
|
+
* // Use context.prompt as the main prompt
|
|
155
|
+
* // Use context.messages for conversation history
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export async function buildConversationContext(triggerMessage, channel, botUserId, options = {}) {
|
|
159
|
+
const { maxMessages = 10, includeBotMessages = true, prioritizeUserMessages = true, } = options;
|
|
160
|
+
// Process the trigger message
|
|
161
|
+
const wasMentioned = isBotMentioned(triggerMessage, botUserId);
|
|
162
|
+
const prompt = stripBotMention(triggerMessage.content, botUserId);
|
|
163
|
+
// Fetch message history (messages before the trigger)
|
|
164
|
+
// Fetch more than we need to allow for filtering
|
|
165
|
+
const fetchLimit = prioritizeUserMessages ? maxMessages * 2 : maxMessages;
|
|
166
|
+
const history = await fetchMessageHistory(channel, triggerMessage.id, fetchLimit);
|
|
167
|
+
// Convert to array and process
|
|
168
|
+
let processedMessages = Array.from(history.values())
|
|
169
|
+
.map((msg) => processMessage(msg, botUserId))
|
|
170
|
+
.filter((msg) => {
|
|
171
|
+
// Filter out bot messages if not included
|
|
172
|
+
if (!includeBotMessages && msg.isBot) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
// Always filter out empty messages
|
|
176
|
+
if (!msg.content.trim()) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
});
|
|
181
|
+
// If prioritizing user messages, sort to put user messages first
|
|
182
|
+
// then take the limit, then re-sort by timestamp
|
|
183
|
+
if (prioritizeUserMessages && processedMessages.length > maxMessages) {
|
|
184
|
+
// Separate user and bot messages
|
|
185
|
+
const userMessages = processedMessages.filter((m) => !m.isBot);
|
|
186
|
+
const botMessages = processedMessages.filter((m) => m.isBot);
|
|
187
|
+
// Take user messages first, fill remaining with bot messages
|
|
188
|
+
const selectedMessages = [
|
|
189
|
+
...userMessages.slice(0, maxMessages),
|
|
190
|
+
...botMessages.slice(0, Math.max(0, maxMessages - userMessages.length)),
|
|
191
|
+
].slice(0, maxMessages);
|
|
192
|
+
// Sort by timestamp (oldest first)
|
|
193
|
+
processedMessages = selectedMessages.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// Take messages and sort by timestamp (oldest first) for chronological order
|
|
197
|
+
processedMessages = processedMessages
|
|
198
|
+
.slice(0, maxMessages)
|
|
199
|
+
.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
messages: processedMessages,
|
|
203
|
+
prompt,
|
|
204
|
+
wasMentioned,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Format conversation context as a string for Claude
|
|
209
|
+
*
|
|
210
|
+
* Creates a formatted string representation of the conversation context
|
|
211
|
+
* suitable for including in a prompt to Claude.
|
|
212
|
+
*
|
|
213
|
+
* @param context - The conversation context to format
|
|
214
|
+
* @returns Formatted string representation
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* const formatted = formatContextForPrompt(context);
|
|
219
|
+
* // Returns:
|
|
220
|
+
* // [User123 at 2024-01-20T10:00:00Z]: How do I use this feature?
|
|
221
|
+
* // [BotName at 2024-01-20T10:00:30Z]: Here's how you can...
|
|
222
|
+
* // [User123 at 2024-01-20T10:01:00Z]: Thanks, but what about...
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export function formatContextForPrompt(context) {
|
|
226
|
+
if (context.messages.length === 0) {
|
|
227
|
+
return "";
|
|
228
|
+
}
|
|
229
|
+
return context.messages
|
|
230
|
+
.map((msg) => {
|
|
231
|
+
const authorLabel = msg.isBot ? `${msg.authorName} (bot)` : msg.authorName;
|
|
232
|
+
return `[${authorLabel} at ${msg.timestamp}]: ${msg.content}`;
|
|
233
|
+
})
|
|
234
|
+
.join("\n");
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=mention-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-handler.js","sourceRoot":"","sources":["../src/mention-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAyDH,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB,EAAE,SAAiB;IAChE,yCAAyC;IACzC,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,SAAiB,EACjB,IAAwB;IAExB,oDAAoD;IACpD,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+CAA+C;IAC/C,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sDAAsD;IACtD,OAAO,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,SAAiB;IAChE,iEAAiE;IACjE,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,OAAO,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1D,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAClD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,SAAkB;IAC/D,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC;IACD,0BAA0B;IAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAgB,EAChB,SAAiB;IAEjB,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;QAC3B,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ;QACjE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG;QACzB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,SAAS;QACvC,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;QACpD,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;QAC1C,SAAS,EAAE,OAAO,CAAC,EAAE;KACtB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAyB,EACzB,eAAuB,EACvB,KAAa;IAEb,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC5B,MAAM,EAAE,eAAe;QACvB,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,cAAuB,EACvB,OAAyB,EACzB,SAAiB,EACjB,UAA+B,EAAE;IAEjC,MAAM,EACJ,WAAW,GAAG,EAAE,EAChB,kBAAkB,GAAG,IAAI,EACzB,sBAAsB,GAAG,IAAI,GAC9B,GAAG,OAAO,CAAC;IAEZ,8BAA8B;IAC9B,MAAM,YAAY,GAAG,cAAc,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,eAAe,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAElE,sDAAsD;IACtD,iDAAiD;IACjD,MAAM,UAAU,GAAG,sBAAsB,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IAC1E,MAAM,OAAO,GAAG,MAAM,mBAAmB,CACvC,OAAO,EACP,cAAc,CAAC,EAAE,EACjB,UAAU,CACX,CAAC;IAEF,+BAA+B;IAC/B,IAAI,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;SACjD,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;SAC5C,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QACd,0CAA0C;QAC1C,IAAI,CAAC,kBAAkB,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,mCAAmC;QACnC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEL,iEAAiE;IACjE,iDAAiD;IACjD,IAAI,sBAAsB,IAAI,iBAAiB,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;QACrE,iCAAiC;QACjC,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/D,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAE7D,6DAA6D;QAC7D,MAAM,gBAAgB,GAAG;YACvB,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC;YACrC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;SACxE,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAExB,mCAAmC;QACnC,iBAAiB,GAAG,gBAAgB,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CACpE,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,6EAA6E;QAC7E,iBAAiB,GAAG,iBAAiB;aAClC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC;aACrB,IAAI,CACH,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CACpE,CAAC;IACN,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,iBAAiB;QAC3B,MAAM;QACN,YAAY;KACb,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAA4B;IACjE,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,OAAO,CAAC,QAAQ;SACpB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC;QAC3E,OAAO,IAAI,WAAW,OAAO,GAAG,CAAC,SAAS,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;IAChE,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../../src/session-manager/__tests__/errors.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { SessionErrorCode, SessionManagerError, SessionStateReadError, SessionStateWriteError, SessionDirectoryCreateError, isSessionManagerError, } from "../errors.js";
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// SessionManagerError Tests
|
|
5
|
+
// =============================================================================
|
|
6
|
+
describe("SessionManagerError", () => {
|
|
7
|
+
it("creates error with correct properties", () => {
|
|
8
|
+
const error = new SessionManagerError("Test error message", SessionErrorCode.STATE_READ_FAILED, "test-agent");
|
|
9
|
+
expect(error.message).toBe("Test error message");
|
|
10
|
+
expect(error.code).toBe(SessionErrorCode.STATE_READ_FAILED);
|
|
11
|
+
expect(error.agentName).toBe("test-agent");
|
|
12
|
+
expect(error.name).toBe("SessionManagerError");
|
|
13
|
+
});
|
|
14
|
+
it("accepts cause option", () => {
|
|
15
|
+
const cause = new Error("Original error");
|
|
16
|
+
const error = new SessionManagerError("Wrapper error", SessionErrorCode.STATE_WRITE_FAILED, "test-agent", { cause });
|
|
17
|
+
expect(error.cause).toBe(cause);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// SessionStateReadError Tests
|
|
22
|
+
// =============================================================================
|
|
23
|
+
describe("SessionStateReadError", () => {
|
|
24
|
+
it("creates error with correct message and properties", () => {
|
|
25
|
+
const error = new SessionStateReadError("my-agent", "/path/to/state.yaml");
|
|
26
|
+
expect(error.message).toBe("Failed to read session state for agent 'my-agent' from '/path/to/state.yaml'");
|
|
27
|
+
expect(error.code).toBe(SessionErrorCode.STATE_READ_FAILED);
|
|
28
|
+
expect(error.agentName).toBe("my-agent");
|
|
29
|
+
expect(error.path).toBe("/path/to/state.yaml");
|
|
30
|
+
expect(error.name).toBe("SessionStateReadError");
|
|
31
|
+
});
|
|
32
|
+
it("accepts cause option", () => {
|
|
33
|
+
const cause = new Error("ENOENT");
|
|
34
|
+
const error = new SessionStateReadError("my-agent", "/path/to/state.yaml", { cause });
|
|
35
|
+
expect(error.cause).toBe(cause);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// SessionStateWriteError Tests
|
|
40
|
+
// =============================================================================
|
|
41
|
+
describe("SessionStateWriteError", () => {
|
|
42
|
+
it("creates error with correct message and properties", () => {
|
|
43
|
+
const error = new SessionStateWriteError("my-agent", "/path/to/state.yaml");
|
|
44
|
+
expect(error.message).toBe("Failed to write session state for agent 'my-agent' to '/path/to/state.yaml'");
|
|
45
|
+
expect(error.code).toBe(SessionErrorCode.STATE_WRITE_FAILED);
|
|
46
|
+
expect(error.agentName).toBe("my-agent");
|
|
47
|
+
expect(error.path).toBe("/path/to/state.yaml");
|
|
48
|
+
expect(error.name).toBe("SessionStateWriteError");
|
|
49
|
+
});
|
|
50
|
+
it("accepts cause option", () => {
|
|
51
|
+
const cause = new Error("EACCES");
|
|
52
|
+
const error = new SessionStateWriteError("my-agent", "/path/to/state.yaml", { cause });
|
|
53
|
+
expect(error.cause).toBe(cause);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
// =============================================================================
|
|
57
|
+
// SessionDirectoryCreateError Tests
|
|
58
|
+
// =============================================================================
|
|
59
|
+
describe("SessionDirectoryCreateError", () => {
|
|
60
|
+
it("creates error with correct message and properties", () => {
|
|
61
|
+
const error = new SessionDirectoryCreateError("my-agent", "/path/to/sessions");
|
|
62
|
+
expect(error.message).toBe("Failed to create session directory for agent 'my-agent' at '/path/to/sessions'");
|
|
63
|
+
expect(error.code).toBe(SessionErrorCode.DIRECTORY_CREATE_FAILED);
|
|
64
|
+
expect(error.agentName).toBe("my-agent");
|
|
65
|
+
expect(error.path).toBe("/path/to/sessions");
|
|
66
|
+
expect(error.name).toBe("SessionDirectoryCreateError");
|
|
67
|
+
});
|
|
68
|
+
it("accepts cause option", () => {
|
|
69
|
+
const cause = new Error("EPERM");
|
|
70
|
+
const error = new SessionDirectoryCreateError("my-agent", "/path/to/sessions", { cause });
|
|
71
|
+
expect(error.cause).toBe(cause);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// isSessionManagerError Tests
|
|
76
|
+
// =============================================================================
|
|
77
|
+
describe("isSessionManagerError", () => {
|
|
78
|
+
it("returns true for SessionManagerError", () => {
|
|
79
|
+
const error = new SessionManagerError("Test", SessionErrorCode.STATE_READ_FAILED, "agent");
|
|
80
|
+
expect(isSessionManagerError(error)).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
it("returns true for SessionStateReadError", () => {
|
|
83
|
+
const error = new SessionStateReadError("agent", "/path");
|
|
84
|
+
expect(isSessionManagerError(error)).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
it("returns true for SessionStateWriteError", () => {
|
|
87
|
+
const error = new SessionStateWriteError("agent", "/path");
|
|
88
|
+
expect(isSessionManagerError(error)).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
it("returns true for SessionDirectoryCreateError", () => {
|
|
91
|
+
const error = new SessionDirectoryCreateError("agent", "/path");
|
|
92
|
+
expect(isSessionManagerError(error)).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
it("returns false for regular Error", () => {
|
|
95
|
+
const error = new Error("Not a session error");
|
|
96
|
+
expect(isSessionManagerError(error)).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
it("returns false for null", () => {
|
|
99
|
+
expect(isSessionManagerError(null)).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
it("returns false for undefined", () => {
|
|
102
|
+
expect(isSessionManagerError(undefined)).toBe(false);
|
|
103
|
+
});
|
|
104
|
+
it("returns false for string", () => {
|
|
105
|
+
expect(isSessionManagerError("error")).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
it("returns false for object", () => {
|
|
108
|
+
expect(isSessionManagerError({ message: "error" })).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
// =============================================================================
|
|
112
|
+
// Error Code Tests
|
|
113
|
+
// =============================================================================
|
|
114
|
+
describe("SessionErrorCode", () => {
|
|
115
|
+
it("has all expected error codes", () => {
|
|
116
|
+
expect(SessionErrorCode.STATE_READ_FAILED).toBe("SESSION_STATE_READ_FAILED");
|
|
117
|
+
expect(SessionErrorCode.STATE_WRITE_FAILED).toBe("SESSION_STATE_WRITE_FAILED");
|
|
118
|
+
expect(SessionErrorCode.DIRECTORY_CREATE_FAILED).toBe("SESSION_DIRECTORY_CREATE_FAILED");
|
|
119
|
+
expect(SessionErrorCode.SESSION_NOT_FOUND).toBe("SESSION_NOT_FOUND");
|
|
120
|
+
expect(SessionErrorCode.SESSION_EXPIRED).toBe("SESSION_EXPIRED");
|
|
121
|
+
expect(SessionErrorCode.INVALID_STATE).toBe("SESSION_INVALID_STATE");
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=errors.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../../../src/session-manager/__tests__/errors.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.test.d.ts","sourceRoot":"","sources":["../../../src/session-manager/__tests__/session-manager.test.ts"],"names":[],"mappings":""}
|