@herdctl/chat 0.0.1 → 0.2.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/LICENSE +21 -0
- package/dist/__tests__/dm-filter.test.d.ts +5 -0
- package/dist/__tests__/dm-filter.test.d.ts.map +1 -0
- package/dist/__tests__/dm-filter.test.js +136 -0
- package/dist/__tests__/dm-filter.test.js.map +1 -0
- package/dist/__tests__/error-handler.test.d.ts +5 -0
- package/dist/__tests__/error-handler.test.d.ts.map +1 -0
- package/dist/__tests__/error-handler.test.js +235 -0
- package/dist/__tests__/error-handler.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +5 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +140 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/index.test.d.ts +2 -0
- package/dist/__tests__/index.test.d.ts.map +1 -0
- package/dist/__tests__/index.test.js +25 -0
- package/dist/__tests__/index.test.js.map +1 -0
- package/dist/__tests__/message-extraction.test.d.ts +5 -0
- package/dist/__tests__/message-extraction.test.d.ts.map +1 -0
- package/dist/__tests__/message-extraction.test.js +157 -0
- package/dist/__tests__/message-extraction.test.js.map +1 -0
- package/dist/__tests__/message-splitting.test.d.ts +5 -0
- package/dist/__tests__/message-splitting.test.d.ts.map +1 -0
- package/dist/__tests__/message-splitting.test.js +153 -0
- package/dist/__tests__/message-splitting.test.js.map +1 -0
- package/dist/__tests__/session-manager.test.d.ts +2 -0
- package/dist/__tests__/session-manager.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager.test.js +779 -0
- package/dist/__tests__/session-manager.test.js.map +1 -0
- package/dist/__tests__/status-formatting.test.d.ts +5 -0
- package/dist/__tests__/status-formatting.test.d.ts.map +1 -0
- package/dist/__tests__/status-formatting.test.js +160 -0
- package/dist/__tests__/status-formatting.test.js.map +1 -0
- package/dist/__tests__/streaming-responder.test.d.ts +5 -0
- package/dist/__tests__/streaming-responder.test.d.ts.map +1 -0
- package/dist/__tests__/streaming-responder.test.js +154 -0
- package/dist/__tests__/streaming-responder.test.js.map +1 -0
- package/dist/dm-filter.d.ts +121 -0
- package/dist/dm-filter.d.ts.map +1 -0
- package/dist/dm-filter.js +162 -0
- package/dist/dm-filter.js.map +1 -0
- package/dist/error-handler.d.ts +217 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +313 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/errors.d.ts +118 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +157 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/message-extraction.d.ts +81 -0
- package/dist/message-extraction.d.ts.map +1 -0
- package/dist/message-extraction.js +90 -0
- package/dist/message-extraction.js.map +1 -0
- package/dist/message-splitting.d.ts +133 -0
- package/dist/message-splitting.d.ts.map +1 -0
- package/dist/message-splitting.js +188 -0
- package/dist/message-splitting.js.map +1 -0
- package/dist/session-manager/errors.d.ts +59 -0
- package/dist/session-manager/errors.d.ts.map +1 -0
- package/dist/session-manager/errors.js +71 -0
- package/dist/session-manager/errors.js.map +1 -0
- package/dist/session-manager/index.d.ts +10 -0
- package/dist/session-manager/index.d.ts.map +1 -0
- package/dist/session-manager/index.js +14 -0
- package/dist/session-manager/index.js.map +1 -0
- package/dist/session-manager/session-manager.d.ts +123 -0
- package/dist/session-manager/session-manager.d.ts.map +1 -0
- package/dist/session-manager/session-manager.js +394 -0
- package/dist/session-manager/session-manager.js.map +1 -0
- package/dist/session-manager/types.d.ts +205 -0
- package/dist/session-manager/types.d.ts.map +1 -0
- package/dist/session-manager/types.js +67 -0
- package/dist/session-manager/types.js.map +1 -0
- package/dist/status-formatting.d.ts +147 -0
- package/dist/status-formatting.d.ts.map +1 -0
- package/dist/status-formatting.js +234 -0
- package/dist/status-formatting.js.map +1 -0
- package/dist/streaming-responder.d.ts +130 -0
- package/dist/streaming-responder.d.ts.map +1 -0
- package/dist/streaming-responder.js +178 -0
- package/dist/streaming-responder.js.map +1 -0
- package/dist/types.d.ts +184 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -4
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming Responder for chat platforms
|
|
3
|
+
*
|
|
4
|
+
* Handles incremental message delivery to chat platforms with:
|
|
5
|
+
* - Message buffering
|
|
6
|
+
* - Rate limiting between sends
|
|
7
|
+
* - Automatic message splitting for platform limits
|
|
8
|
+
*/
|
|
9
|
+
import { splitMessage } from "./message-splitting.js";
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// StreamingResponder Class
|
|
12
|
+
// =============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* StreamingResponder handles incremental message delivery to chat platforms
|
|
15
|
+
*
|
|
16
|
+
* Instead of collecting all output and sending at the end, this class:
|
|
17
|
+
* - Buffers incoming content
|
|
18
|
+
* - Sends messages as complete chunks arrive
|
|
19
|
+
* - Respects rate limits by enforcing minimum intervals between sends
|
|
20
|
+
* - Handles message splitting for content exceeding platform limits
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const streamer = new StreamingResponder({
|
|
25
|
+
* reply: (content) => channel.send(content),
|
|
26
|
+
* logger: myLogger,
|
|
27
|
+
* agentName: 'my-agent',
|
|
28
|
+
* maxMessageLength: 2000, // Discord
|
|
29
|
+
* maxBufferSize: 1500,
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // Add content as it arrives
|
|
33
|
+
* await streamer.addContent("Hello ");
|
|
34
|
+
* await streamer.addContent("world!");
|
|
35
|
+
*
|
|
36
|
+
* // Flush any remaining content when done
|
|
37
|
+
* await streamer.flush();
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export class StreamingResponder {
|
|
41
|
+
buffer = "";
|
|
42
|
+
lastSendTime = 0;
|
|
43
|
+
messagesSent = 0;
|
|
44
|
+
reply;
|
|
45
|
+
logger;
|
|
46
|
+
agentName;
|
|
47
|
+
maxMessageLength;
|
|
48
|
+
minMessageInterval;
|
|
49
|
+
maxBufferSize;
|
|
50
|
+
platformName;
|
|
51
|
+
constructor(options) {
|
|
52
|
+
this.reply = options.reply;
|
|
53
|
+
this.logger = options.logger;
|
|
54
|
+
this.agentName = options.agentName;
|
|
55
|
+
this.maxMessageLength = options.maxMessageLength;
|
|
56
|
+
this.minMessageInterval = options.minMessageInterval ?? 1000;
|
|
57
|
+
this.maxBufferSize = options.maxBufferSize ?? options.maxMessageLength - 500;
|
|
58
|
+
this.platformName = options.platformName ?? "chat";
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Add content to the buffer
|
|
62
|
+
*
|
|
63
|
+
* Content is accumulated until flush() is called or buffer exceeds maxBufferSize.
|
|
64
|
+
*
|
|
65
|
+
* @param content - Text content to add
|
|
66
|
+
*/
|
|
67
|
+
addContent(content) {
|
|
68
|
+
if (!content) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
this.buffer += content;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Add a complete message and send it immediately (with rate limiting)
|
|
75
|
+
*
|
|
76
|
+
* Use this for complete assistant message turns from the SDK.
|
|
77
|
+
* Each assistant message is a complete response that should be sent.
|
|
78
|
+
*
|
|
79
|
+
* @param content - Complete message content to send
|
|
80
|
+
*/
|
|
81
|
+
async addMessageAndSend(content) {
|
|
82
|
+
if (!content || content.trim().length === 0) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Add to any existing buffer (in case there's leftover content)
|
|
86
|
+
this.buffer += content;
|
|
87
|
+
// Send everything in the buffer
|
|
88
|
+
await this.sendAll();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Flush any remaining content in the buffer
|
|
92
|
+
*
|
|
93
|
+
* Should be called when message processing is complete to ensure
|
|
94
|
+
* all content is sent.
|
|
95
|
+
*/
|
|
96
|
+
async flush() {
|
|
97
|
+
await this.sendAll();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if any messages have been sent
|
|
101
|
+
*
|
|
102
|
+
* @returns true if at least one message has been sent
|
|
103
|
+
*/
|
|
104
|
+
hasSentAnything() {
|
|
105
|
+
return this.messagesSent > 0;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Alias for hasSentAnything() for backward compatibility
|
|
109
|
+
*/
|
|
110
|
+
hasSentMessages() {
|
|
111
|
+
return this.hasSentAnything();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get the number of messages sent
|
|
115
|
+
*/
|
|
116
|
+
getMessagesSent() {
|
|
117
|
+
return this.messagesSent;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get the current buffer content (for debugging)
|
|
121
|
+
*/
|
|
122
|
+
getBufferContent() {
|
|
123
|
+
return this.buffer;
|
|
124
|
+
}
|
|
125
|
+
// ===========================================================================
|
|
126
|
+
// Private Methods
|
|
127
|
+
// ===========================================================================
|
|
128
|
+
/**
|
|
129
|
+
* Send all buffered content immediately (with rate limiting)
|
|
130
|
+
*/
|
|
131
|
+
async sendAll() {
|
|
132
|
+
if (this.buffer.trim().length === 0) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const content = this.buffer.trim();
|
|
136
|
+
this.buffer = "";
|
|
137
|
+
// Respect rate limiting - wait if needed
|
|
138
|
+
const now = Date.now();
|
|
139
|
+
const timeSinceLastSend = now - this.lastSendTime;
|
|
140
|
+
if (timeSinceLastSend < this.minMessageInterval && this.lastSendTime > 0) {
|
|
141
|
+
const waitTime = this.minMessageInterval - timeSinceLastSend;
|
|
142
|
+
await this.sleep(waitTime);
|
|
143
|
+
}
|
|
144
|
+
// Split if needed for platform limits
|
|
145
|
+
const { chunks } = splitMessage(content, { maxLength: this.maxMessageLength });
|
|
146
|
+
for (const chunk of chunks) {
|
|
147
|
+
try {
|
|
148
|
+
await this.reply(chunk);
|
|
149
|
+
this.messagesSent++;
|
|
150
|
+
this.lastSendTime = Date.now();
|
|
151
|
+
this.logger.debug(`Streamed ${this.platformName} message`, {
|
|
152
|
+
agentName: this.agentName,
|
|
153
|
+
chunkLength: chunk.length,
|
|
154
|
+
totalSent: this.messagesSent,
|
|
155
|
+
});
|
|
156
|
+
// Small delay between multiple chunks from same content
|
|
157
|
+
if (chunks.length > 1) {
|
|
158
|
+
await this.sleep(500);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
163
|
+
this.logger.error(`Failed to send ${this.platformName} message`, {
|
|
164
|
+
agentName: this.agentName,
|
|
165
|
+
error: errorMessage,
|
|
166
|
+
});
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Sleep for a given number of milliseconds
|
|
173
|
+
*/
|
|
174
|
+
sleep(ms) {
|
|
175
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=streaming-responder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming-responder.js","sourceRoot":"","sources":["../src/streaming-responder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AA2CtD,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,kBAAkB;IACrB,MAAM,GAAW,EAAE,CAAC;IACpB,YAAY,GAAW,CAAC,CAAC;IACzB,YAAY,GAAW,CAAC,CAAC;IAEhB,KAAK,CAAqC;IAC1C,MAAM,CAAsB;IAC5B,SAAS,CAAS;IAClB,gBAAgB,CAAS;IACzB,kBAAkB,CAAS;IAC3B,aAAa,CAAS;IACtB,YAAY,CAAS;IAEtC,YAAY,OAAkC;QAC5C,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,IAAI,CAAC;QAC7D,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC;QAC7E,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAC;IACrD,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,OAAe;QACxB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,iBAAiB,CAAC,OAAe;QACrC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC;QAEvB,gCAAgC;QAChC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;OAEG;IACK,KAAK,CAAC,OAAO;QACnB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAEjB,yCAAyC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC;QAClD,IAAI,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;YACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;YAC7D,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;QAED,sCAAsC;QACtC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAE/E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxB,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,YAAY,UAAU,EAAE;oBACzD,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,WAAW,EAAE,KAAK,CAAC,MAAM;oBACzB,SAAS,EAAE,IAAI,CAAC,YAAY;iBAC7B,CAAC,CAAC;gBAEH,wDAAwD;gBACxD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,CAAC,YAAY,UAAU,EAAE;oBAC/D,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,KAAK,EAAE,YAAY;iBACpB,CAAC,CAAC;gBACH,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,EAAU;QACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type definitions for chat connectors
|
|
3
|
+
*
|
|
4
|
+
* These types define the common interfaces used across all chat platform
|
|
5
|
+
* integrations (Discord, Slack, etc.).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Chat connector connection status
|
|
9
|
+
*
|
|
10
|
+
* This is identical across all platforms.
|
|
11
|
+
*/
|
|
12
|
+
export type ChatConnectionStatus = "disconnected" | "connecting" | "connected" | "reconnecting" | "disconnecting" | "error";
|
|
13
|
+
/**
|
|
14
|
+
* Base connector state that all platforms share
|
|
15
|
+
*
|
|
16
|
+
* Platform-specific implementations may extend this with additional fields.
|
|
17
|
+
*/
|
|
18
|
+
export interface ChatConnectorState {
|
|
19
|
+
/** Current connection status */
|
|
20
|
+
status: ChatConnectionStatus;
|
|
21
|
+
/** ISO timestamp when the connector connected */
|
|
22
|
+
connectedAt: string | null;
|
|
23
|
+
/** ISO timestamp when the connector disconnected */
|
|
24
|
+
disconnectedAt: string | null;
|
|
25
|
+
/** Number of reconnect attempts since last successful connection */
|
|
26
|
+
reconnectAttempts: number;
|
|
27
|
+
/** Last error message if status is 'error' */
|
|
28
|
+
lastError: string | null;
|
|
29
|
+
/** Bot user info (only present when connected) */
|
|
30
|
+
botUser: {
|
|
31
|
+
id: string;
|
|
32
|
+
username: string;
|
|
33
|
+
} | null;
|
|
34
|
+
/** Message statistics since connection */
|
|
35
|
+
messageStats: {
|
|
36
|
+
/** Total messages received and processed */
|
|
37
|
+
received: number;
|
|
38
|
+
/** Total messages sent (replies) */
|
|
39
|
+
sent: number;
|
|
40
|
+
/** Total messages ignored (not mentioned, bot messages, etc.) */
|
|
41
|
+
ignored: number;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Session manager interface for chat connectors
|
|
46
|
+
*
|
|
47
|
+
* Minimal interface for session management in connectors.
|
|
48
|
+
* Keyed by channelId for both Discord and Slack.
|
|
49
|
+
*/
|
|
50
|
+
export interface IChatSessionManager {
|
|
51
|
+
readonly agentName: string;
|
|
52
|
+
getOrCreateSession(channelId: string): Promise<{
|
|
53
|
+
sessionId: string;
|
|
54
|
+
isNew: boolean;
|
|
55
|
+
}>;
|
|
56
|
+
getSession(channelId: string): Promise<{
|
|
57
|
+
sessionId: string;
|
|
58
|
+
lastMessageAt: string;
|
|
59
|
+
} | null>;
|
|
60
|
+
setSession(channelId: string, sessionId: string): Promise<void>;
|
|
61
|
+
touchSession(channelId: string): Promise<void>;
|
|
62
|
+
clearSession(channelId: string): Promise<boolean>;
|
|
63
|
+
cleanupExpiredSessions(): Promise<number>;
|
|
64
|
+
getActiveSessionCount(): Promise<number>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Base interface for chat connectors
|
|
68
|
+
*
|
|
69
|
+
* All chat platform connectors (Discord, Slack, etc.) implement this interface.
|
|
70
|
+
*/
|
|
71
|
+
export interface IChatConnector {
|
|
72
|
+
/** Name of the agent this connector is bound to */
|
|
73
|
+
readonly agentName: string;
|
|
74
|
+
/** Session manager for this agent */
|
|
75
|
+
readonly sessionManager: IChatSessionManager;
|
|
76
|
+
/** Connect to the chat platform */
|
|
77
|
+
connect(): Promise<void>;
|
|
78
|
+
/** Disconnect from the chat platform */
|
|
79
|
+
disconnect(): Promise<void>;
|
|
80
|
+
/** Check if currently connected */
|
|
81
|
+
isConnected(): boolean;
|
|
82
|
+
/** Get current connector state */
|
|
83
|
+
getState(): ChatConnectorState;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Logger interface for chat connector operations
|
|
87
|
+
*
|
|
88
|
+
* All connectors accept a logger with this interface.
|
|
89
|
+
*/
|
|
90
|
+
export interface ChatConnectorLogger {
|
|
91
|
+
debug(message: string, data?: Record<string, unknown>): void;
|
|
92
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
93
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
94
|
+
error(message: string, data?: Record<string, unknown>): void;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Base metadata for chat messages
|
|
98
|
+
*/
|
|
99
|
+
export interface ChatMessageMetadata {
|
|
100
|
+
/** Channel ID where the message was sent */
|
|
101
|
+
channelId: string;
|
|
102
|
+
/** User ID who sent the message */
|
|
103
|
+
userId: string;
|
|
104
|
+
/** Whether this was triggered by a mention */
|
|
105
|
+
wasMentioned: boolean;
|
|
106
|
+
/** Allow additional platform-specific fields */
|
|
107
|
+
[key: string]: unknown;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Base message event from chat connectors
|
|
111
|
+
*
|
|
112
|
+
* This is emitted when a processable message is received.
|
|
113
|
+
* Platform-specific connectors may extend this with additional fields.
|
|
114
|
+
*/
|
|
115
|
+
export interface ChatMessageEvent {
|
|
116
|
+
/** Name of the agent handling this message */
|
|
117
|
+
agentName: string;
|
|
118
|
+
/** The processed prompt text (with mention stripped) */
|
|
119
|
+
prompt: string;
|
|
120
|
+
/** Platform-specific metadata */
|
|
121
|
+
metadata: ChatMessageMetadata;
|
|
122
|
+
/** Function to send a reply in the same channel/thread */
|
|
123
|
+
reply: (content: string) => Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Start showing processing indicator.
|
|
126
|
+
* Returns a stop function that should be called when done.
|
|
127
|
+
*/
|
|
128
|
+
startProcessingIndicator: () => () => void;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Session lifecycle event types
|
|
132
|
+
*/
|
|
133
|
+
export type SessionLifecycleEvent = "created" | "resumed" | "expired" | "cleared";
|
|
134
|
+
/**
|
|
135
|
+
* Base event map for chat connectors
|
|
136
|
+
*
|
|
137
|
+
* All connectors emit these events. Platform-specific connectors may
|
|
138
|
+
* add additional events.
|
|
139
|
+
*/
|
|
140
|
+
export interface ChatConnectorEventMap {
|
|
141
|
+
/** Emitted when connection is established and ready */
|
|
142
|
+
ready: {
|
|
143
|
+
agentName: string;
|
|
144
|
+
botUser: {
|
|
145
|
+
id: string;
|
|
146
|
+
username: string;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
/** Emitted when connection is lost */
|
|
150
|
+
disconnect: {
|
|
151
|
+
agentName: string;
|
|
152
|
+
reason: string;
|
|
153
|
+
};
|
|
154
|
+
/** Emitted on connection error */
|
|
155
|
+
error: {
|
|
156
|
+
agentName: string;
|
|
157
|
+
error: Error;
|
|
158
|
+
};
|
|
159
|
+
/** Emitted when a processable message is received */
|
|
160
|
+
message: ChatMessageEvent;
|
|
161
|
+
/** Emitted when a message is ignored */
|
|
162
|
+
messageIgnored: {
|
|
163
|
+
agentName: string;
|
|
164
|
+
reason: string;
|
|
165
|
+
channelId: string;
|
|
166
|
+
};
|
|
167
|
+
/** Emitted when a command is executed */
|
|
168
|
+
commandExecuted: {
|
|
169
|
+
agentName: string;
|
|
170
|
+
commandName: string;
|
|
171
|
+
userId: string;
|
|
172
|
+
channelId: string;
|
|
173
|
+
};
|
|
174
|
+
/** Emitted when a session is created, resumed, expired, or cleared */
|
|
175
|
+
sessionLifecycle: {
|
|
176
|
+
agentName: string;
|
|
177
|
+
event: SessionLifecycleEvent;
|
|
178
|
+
channelId: string;
|
|
179
|
+
sessionId: string;
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
export type ChatConnectorEventName = keyof ChatConnectorEventMap;
|
|
183
|
+
export type ChatConnectorEventPayload<E extends ChatConnectorEventName> = ChatConnectorEventMap[E];
|
|
184
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herdctl/chat",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Shared chat infrastructure for herdctl connectors
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Shared chat infrastructure for herdctl connectors",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"yaml": "^2.3.0",
|
|
14
|
+
"zod": "^3.22.0",
|
|
15
|
+
"@herdctl/core": "5.1.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@vitest/coverage-v8": "^4.0.17",
|
|
19
|
+
"typescript": "^5",
|
|
20
|
+
"vitest": "^4.0.17"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://herdctl.dev",
|
|
6
23
|
"repository": {
|
|
7
24
|
"type": "git",
|
|
8
25
|
"url": "https://github.com/edspencer/herdctl"
|
|
9
26
|
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"claude",
|
|
29
|
+
"agent",
|
|
30
|
+
"fleet",
|
|
31
|
+
"orchestration",
|
|
32
|
+
"anthropic",
|
|
33
|
+
"chat"
|
|
34
|
+
],
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
10
38
|
"publishConfig": {
|
|
11
|
-
"access": "public"
|
|
39
|
+
"access": "public",
|
|
40
|
+
"provenance": true
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc",
|
|
44
|
+
"dev": "tsc --watch",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"test": "vitest run --coverage"
|
|
12
47
|
}
|
|
13
|
-
}
|
|
48
|
+
}
|