@herdctl/web 0.0.1 → 0.1.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/README.md +146 -0
- package/dist/client/assets/index-Cyochp2F.css +1 -0
- package/dist/client/assets/index-mp9jz5eD.js +373 -0
- package/dist/client/favicon.ico +0 -0
- package/dist/client/favicon.svg +1 -0
- package/dist/client/herdctl-logo.svg +29 -0
- package/dist/client/index.html +21 -0
- package/dist/server/__tests__/routes.test.d.ts +8 -0
- package/dist/server/__tests__/routes.test.d.ts.map +1 -0
- package/dist/server/__tests__/routes.test.js +535 -0
- package/dist/server/__tests__/routes.test.js.map +1 -0
- package/dist/server/__tests__/ws-handler.test.d.ts +7 -0
- package/dist/server/__tests__/ws-handler.test.d.ts.map +1 -0
- package/dist/server/__tests__/ws-handler.test.js +380 -0
- package/dist/server/__tests__/ws-handler.test.js.map +1 -0
- package/dist/server/chat/index.d.ts +5 -0
- package/dist/server/chat/index.d.ts.map +1 -0
- package/dist/server/chat/index.js +5 -0
- package/dist/server/chat/index.js.map +1 -0
- package/dist/server/chat/web-chat-manager.d.ts +158 -0
- package/dist/server/chat/web-chat-manager.d.ts.map +1 -0
- package/dist/server/chat/web-chat-manager.js +437 -0
- package/dist/server/chat/web-chat-manager.js.map +1 -0
- package/dist/server/index.d.ts +144 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +341 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/agents.d.ts +15 -0
- package/dist/server/routes/agents.d.ts.map +1 -0
- package/dist/server/routes/agents.js +66 -0
- package/dist/server/routes/agents.js.map +1 -0
- package/dist/server/routes/chat.d.ts +18 -0
- package/dist/server/routes/chat.d.ts.map +1 -0
- package/dist/server/routes/chat.js +191 -0
- package/dist/server/routes/chat.js.map +1 -0
- package/dist/server/routes/fleet.d.ts +15 -0
- package/dist/server/routes/fleet.d.ts.map +1 -0
- package/dist/server/routes/fleet.js +36 -0
- package/dist/server/routes/fleet.js.map +1 -0
- package/dist/server/routes/jobs.d.ts +17 -0
- package/dist/server/routes/jobs.d.ts.map +1 -0
- package/dist/server/routes/jobs.js +188 -0
- package/dist/server/routes/jobs.js.map +1 -0
- package/dist/server/routes/schedules.d.ts +16 -0
- package/dist/server/routes/schedules.d.ts.map +1 -0
- package/dist/server/routes/schedules.js +126 -0
- package/dist/server/routes/schedules.js.map +1 -0
- package/dist/server/ws/fleet-bridge.d.ts +80 -0
- package/dist/server/ws/fleet-bridge.d.ts.map +1 -0
- package/dist/server/ws/fleet-bridge.js +184 -0
- package/dist/server/ws/fleet-bridge.js.map +1 -0
- package/dist/server/ws/handler.d.ts +93 -0
- package/dist/server/ws/handler.d.ts.map +1 -0
- package/dist/server/ws/handler.js +270 -0
- package/dist/server/ws/handler.js.map +1 -0
- package/dist/server/ws/index.d.ts +8 -0
- package/dist/server/ws/index.d.ts.map +1 -0
- package/dist/server/ws/index.js +8 -0
- package/dist/server/ws/index.js.map +1 -0
- package/dist/server/ws/types.d.ts +215 -0
- package/dist/server/ws/types.d.ts.map +1 -0
- package/dist/server/ws/types.js +67 -0
- package/dist/server/ws/types.js.map +1 -0
- package/package.json +77 -1
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket handler and type guard tests for @herdctl/web
|
|
3
|
+
*
|
|
4
|
+
* Tests the WebSocket message type guards and handler behavior.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
7
|
+
import { isClientMessage, isChatSendMessage, isAgentStartedPayload, isAgentStoppedPayload } from "../ws/types.js";
|
|
8
|
+
import { WebSocketHandler } from "../ws/handler.js";
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Type Guard Tests
|
|
11
|
+
// =============================================================================
|
|
12
|
+
describe("isClientMessage", () => {
|
|
13
|
+
it("accepts a valid subscribe message", () => {
|
|
14
|
+
expect(isClientMessage({ type: "subscribe", payload: { agentName: "coder" } })).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it("accepts a valid unsubscribe message", () => {
|
|
17
|
+
expect(isClientMessage({ type: "unsubscribe", payload: { agentName: "coder" } })).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it("accepts a valid ping message", () => {
|
|
20
|
+
expect(isClientMessage({ type: "ping" })).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
it("accepts a valid chat:send message", () => {
|
|
23
|
+
expect(isClientMessage({
|
|
24
|
+
type: "chat:send",
|
|
25
|
+
payload: {
|
|
26
|
+
agentName: "coder",
|
|
27
|
+
sessionId: "session-1",
|
|
28
|
+
message: "Hello",
|
|
29
|
+
},
|
|
30
|
+
})).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
it("rejects null", () => {
|
|
33
|
+
expect(isClientMessage(null)).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
it("rejects non-objects", () => {
|
|
36
|
+
expect(isClientMessage("string")).toBe(false);
|
|
37
|
+
expect(isClientMessage(42)).toBe(false);
|
|
38
|
+
expect(isClientMessage(undefined)).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
it("rejects object without type", () => {
|
|
41
|
+
expect(isClientMessage({ payload: { agentName: "coder" } })).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
it("rejects unknown type", () => {
|
|
44
|
+
expect(isClientMessage({ type: "unknown" })).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
it("rejects subscribe without agentName", () => {
|
|
47
|
+
expect(isClientMessage({ type: "subscribe", payload: {} })).toBe(false);
|
|
48
|
+
expect(isClientMessage({ type: "subscribe", payload: null })).toBe(false);
|
|
49
|
+
expect(isClientMessage({ type: "subscribe" })).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
it("rejects unsubscribe without agentName", () => {
|
|
52
|
+
expect(isClientMessage({ type: "unsubscribe", payload: {} })).toBe(false);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe("isChatSendMessage", () => {
|
|
56
|
+
it("accepts valid chat:send message", () => {
|
|
57
|
+
expect(isChatSendMessage({
|
|
58
|
+
type: "chat:send",
|
|
59
|
+
payload: {
|
|
60
|
+
agentName: "coder",
|
|
61
|
+
sessionId: "session-1",
|
|
62
|
+
message: "Hello",
|
|
63
|
+
},
|
|
64
|
+
})).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
it("rejects missing payload fields", () => {
|
|
67
|
+
expect(isChatSendMessage({
|
|
68
|
+
type: "chat:send",
|
|
69
|
+
payload: { agentName: "coder", sessionId: "session-1" },
|
|
70
|
+
})).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
it("rejects wrong type", () => {
|
|
73
|
+
expect(isChatSendMessage({
|
|
74
|
+
type: "ping",
|
|
75
|
+
payload: {
|
|
76
|
+
agentName: "coder",
|
|
77
|
+
sessionId: "session-1",
|
|
78
|
+
message: "Hello",
|
|
79
|
+
},
|
|
80
|
+
})).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
it("rejects null payload", () => {
|
|
83
|
+
expect(isChatSendMessage({ type: "chat:send", payload: null })).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
it("rejects non-object", () => {
|
|
86
|
+
expect(isChatSendMessage(null)).toBe(false);
|
|
87
|
+
expect(isChatSendMessage("string")).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe("isAgentStartedPayload", () => {
|
|
91
|
+
it("returns true for started payload", () => {
|
|
92
|
+
expect(isAgentStartedPayload({
|
|
93
|
+
agent: { name: "coder", status: "running" },
|
|
94
|
+
})).toBe(true);
|
|
95
|
+
});
|
|
96
|
+
it("returns false for stopped payload", () => {
|
|
97
|
+
expect(isAgentStartedPayload({
|
|
98
|
+
agentName: "coder",
|
|
99
|
+
reason: "completed",
|
|
100
|
+
})).toBe(false);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe("isAgentStoppedPayload", () => {
|
|
104
|
+
it("returns true for stopped payload", () => {
|
|
105
|
+
expect(isAgentStoppedPayload({
|
|
106
|
+
agentName: "coder",
|
|
107
|
+
reason: "completed",
|
|
108
|
+
})).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
it("returns false for started payload", () => {
|
|
111
|
+
expect(isAgentStoppedPayload({
|
|
112
|
+
agent: { name: "coder", status: "running" },
|
|
113
|
+
})).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
// =============================================================================
|
|
117
|
+
// WebSocketHandler Tests
|
|
118
|
+
// =============================================================================
|
|
119
|
+
describe("WebSocketHandler", () => {
|
|
120
|
+
let mockFleetManager;
|
|
121
|
+
beforeEach(() => {
|
|
122
|
+
mockFleetManager = {
|
|
123
|
+
getFleetStatus: vi.fn().mockResolvedValue({
|
|
124
|
+
state: "running",
|
|
125
|
+
counts: { totalAgents: 1 },
|
|
126
|
+
}),
|
|
127
|
+
on: vi.fn(),
|
|
128
|
+
off: vi.fn(),
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
it("can be instantiated", () => {
|
|
132
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
133
|
+
expect(handler).toBeDefined();
|
|
134
|
+
expect(handler.getConnectedCount()).toBe(0);
|
|
135
|
+
});
|
|
136
|
+
it("reports zero subscribers for unknown agent", () => {
|
|
137
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
138
|
+
expect(handler.getSubscriberCount("nonexistent")).toBe(0);
|
|
139
|
+
});
|
|
140
|
+
it("broadcasts to no clients when none connected", () => {
|
|
141
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
142
|
+
// Should not throw when broadcasting to empty set
|
|
143
|
+
handler.broadcast({ type: "pong" });
|
|
144
|
+
});
|
|
145
|
+
it("broadcastToSubscribers does not throw with no clients", () => {
|
|
146
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
147
|
+
// Should not throw when no one is subscribed
|
|
148
|
+
handler.broadcastToSubscribers("coder", { type: "pong" });
|
|
149
|
+
});
|
|
150
|
+
it("closeAll works on empty handler", () => {
|
|
151
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
152
|
+
// Should not throw
|
|
153
|
+
handler.closeAll();
|
|
154
|
+
expect(handler.getConnectedCount()).toBe(0);
|
|
155
|
+
});
|
|
156
|
+
describe("handleConnection", () => {
|
|
157
|
+
it("tracks connected clients", async () => {
|
|
158
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
159
|
+
const mockSocket = {
|
|
160
|
+
on: vi.fn(),
|
|
161
|
+
readyState: 1,
|
|
162
|
+
OPEN: 1,
|
|
163
|
+
send: vi.fn(),
|
|
164
|
+
close: vi.fn(),
|
|
165
|
+
};
|
|
166
|
+
await handler.handleConnection(mockSocket);
|
|
167
|
+
expect(handler.getConnectedCount()).toBe(1);
|
|
168
|
+
expect(mockSocket.on).toHaveBeenCalledWith("message", expect.any(Function));
|
|
169
|
+
expect(mockSocket.on).toHaveBeenCalledWith("close", expect.any(Function));
|
|
170
|
+
expect(mockSocket.on).toHaveBeenCalledWith("error", expect.any(Function));
|
|
171
|
+
});
|
|
172
|
+
it("sends initial fleet status on connection", async () => {
|
|
173
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
174
|
+
const mockSocket = {
|
|
175
|
+
on: vi.fn(),
|
|
176
|
+
readyState: 1,
|
|
177
|
+
OPEN: 1,
|
|
178
|
+
send: vi.fn(),
|
|
179
|
+
close: vi.fn(),
|
|
180
|
+
};
|
|
181
|
+
await handler.handleConnection(mockSocket);
|
|
182
|
+
expect(mockFleetManager.getFleetStatus).toHaveBeenCalled();
|
|
183
|
+
expect(mockSocket.send).toHaveBeenCalledWith(expect.stringContaining('"type":"fleet:status"'));
|
|
184
|
+
});
|
|
185
|
+
it("handles disconnect", async () => {
|
|
186
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
187
|
+
let closeHandler;
|
|
188
|
+
const mockSocket = {
|
|
189
|
+
on: vi.fn((event, cb) => {
|
|
190
|
+
if (event === "close")
|
|
191
|
+
closeHandler = cb;
|
|
192
|
+
}),
|
|
193
|
+
readyState: 1,
|
|
194
|
+
OPEN: 1,
|
|
195
|
+
send: vi.fn(),
|
|
196
|
+
close: vi.fn(),
|
|
197
|
+
};
|
|
198
|
+
await handler.handleConnection(mockSocket);
|
|
199
|
+
expect(handler.getConnectedCount()).toBe(1);
|
|
200
|
+
// Simulate disconnect
|
|
201
|
+
closeHandler();
|
|
202
|
+
expect(handler.getConnectedCount()).toBe(0);
|
|
203
|
+
});
|
|
204
|
+
it("handles subscribe and unsubscribe messages", async () => {
|
|
205
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
206
|
+
let messageHandler;
|
|
207
|
+
const mockSocket = {
|
|
208
|
+
on: vi.fn((event, cb) => {
|
|
209
|
+
if (event === "message")
|
|
210
|
+
messageHandler = cb;
|
|
211
|
+
}),
|
|
212
|
+
readyState: 1,
|
|
213
|
+
OPEN: 1,
|
|
214
|
+
send: vi.fn(),
|
|
215
|
+
close: vi.fn(),
|
|
216
|
+
};
|
|
217
|
+
await handler.handleConnection(mockSocket);
|
|
218
|
+
// Subscribe to an agent
|
|
219
|
+
const subscribeMsg = JSON.stringify({
|
|
220
|
+
type: "subscribe",
|
|
221
|
+
payload: { agentName: "coder" },
|
|
222
|
+
});
|
|
223
|
+
messageHandler(Buffer.from(subscribeMsg));
|
|
224
|
+
expect(handler.getSubscriberCount("coder")).toBe(1);
|
|
225
|
+
// Unsubscribe from the agent
|
|
226
|
+
const unsubscribeMsg = JSON.stringify({
|
|
227
|
+
type: "unsubscribe",
|
|
228
|
+
payload: { agentName: "coder" },
|
|
229
|
+
});
|
|
230
|
+
messageHandler(Buffer.from(unsubscribeMsg));
|
|
231
|
+
expect(handler.getSubscriberCount("coder")).toBe(0);
|
|
232
|
+
});
|
|
233
|
+
it("responds to ping with pong", async () => {
|
|
234
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
235
|
+
let messageHandler;
|
|
236
|
+
const mockSocket = {
|
|
237
|
+
on: vi.fn((event, cb) => {
|
|
238
|
+
if (event === "message")
|
|
239
|
+
messageHandler = cb;
|
|
240
|
+
}),
|
|
241
|
+
readyState: 1,
|
|
242
|
+
OPEN: 1,
|
|
243
|
+
send: vi.fn(),
|
|
244
|
+
close: vi.fn(),
|
|
245
|
+
};
|
|
246
|
+
await handler.handleConnection(mockSocket);
|
|
247
|
+
// Clear the initial fleet:status send
|
|
248
|
+
mockSocket.send.mockClear();
|
|
249
|
+
const pingMsg = JSON.stringify({ type: "ping" });
|
|
250
|
+
messageHandler(Buffer.from(pingMsg));
|
|
251
|
+
expect(mockSocket.send).toHaveBeenCalledWith(JSON.stringify({ type: "pong" }));
|
|
252
|
+
});
|
|
253
|
+
it("ignores invalid JSON messages", async () => {
|
|
254
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
255
|
+
let messageHandler;
|
|
256
|
+
const mockSocket = {
|
|
257
|
+
on: vi.fn((event, cb) => {
|
|
258
|
+
if (event === "message")
|
|
259
|
+
messageHandler = cb;
|
|
260
|
+
}),
|
|
261
|
+
readyState: 1,
|
|
262
|
+
OPEN: 1,
|
|
263
|
+
send: vi.fn(),
|
|
264
|
+
close: vi.fn(),
|
|
265
|
+
};
|
|
266
|
+
await handler.handleConnection(mockSocket);
|
|
267
|
+
mockSocket.send.mockClear();
|
|
268
|
+
// Should not throw on invalid JSON
|
|
269
|
+
messageHandler(Buffer.from("not valid json"));
|
|
270
|
+
expect(mockSocket.send).not.toHaveBeenCalled();
|
|
271
|
+
});
|
|
272
|
+
it("ignores unknown message types", async () => {
|
|
273
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
274
|
+
let messageHandler;
|
|
275
|
+
const mockSocket = {
|
|
276
|
+
on: vi.fn((event, cb) => {
|
|
277
|
+
if (event === "message")
|
|
278
|
+
messageHandler = cb;
|
|
279
|
+
}),
|
|
280
|
+
readyState: 1,
|
|
281
|
+
OPEN: 1,
|
|
282
|
+
send: vi.fn(),
|
|
283
|
+
close: vi.fn(),
|
|
284
|
+
};
|
|
285
|
+
await handler.handleConnection(mockSocket);
|
|
286
|
+
mockSocket.send.mockClear();
|
|
287
|
+
// Should not throw on unknown type (it's just filtered out)
|
|
288
|
+
messageHandler(Buffer.from(JSON.stringify({ type: "unknown" })));
|
|
289
|
+
expect(mockSocket.send).not.toHaveBeenCalled();
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
describe("broadcast", () => {
|
|
293
|
+
it("sends message to all connected clients", async () => {
|
|
294
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
295
|
+
const socket1 = {
|
|
296
|
+
on: vi.fn(),
|
|
297
|
+
readyState: 1,
|
|
298
|
+
OPEN: 1,
|
|
299
|
+
send: vi.fn(),
|
|
300
|
+
close: vi.fn(),
|
|
301
|
+
};
|
|
302
|
+
const socket2 = {
|
|
303
|
+
on: vi.fn(),
|
|
304
|
+
readyState: 1,
|
|
305
|
+
OPEN: 1,
|
|
306
|
+
send: vi.fn(),
|
|
307
|
+
close: vi.fn(),
|
|
308
|
+
};
|
|
309
|
+
await handler.handleConnection(socket1);
|
|
310
|
+
await handler.handleConnection(socket2);
|
|
311
|
+
expect(handler.getConnectedCount()).toBe(2);
|
|
312
|
+
socket1.send.mockClear();
|
|
313
|
+
socket2.send.mockClear();
|
|
314
|
+
handler.broadcast({ type: "pong" });
|
|
315
|
+
expect(socket1.send).toHaveBeenCalledWith(JSON.stringify({ type: "pong" }));
|
|
316
|
+
expect(socket2.send).toHaveBeenCalledWith(JSON.stringify({ type: "pong" }));
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
describe("broadcastToSubscribers", () => {
|
|
320
|
+
it("sends message only to subscribed clients", async () => {
|
|
321
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
322
|
+
let messageHandler1;
|
|
323
|
+
const socket1 = {
|
|
324
|
+
on: vi.fn((event, cb) => {
|
|
325
|
+
if (event === "message")
|
|
326
|
+
messageHandler1 = cb;
|
|
327
|
+
}),
|
|
328
|
+
readyState: 1,
|
|
329
|
+
OPEN: 1,
|
|
330
|
+
send: vi.fn(),
|
|
331
|
+
close: vi.fn(),
|
|
332
|
+
};
|
|
333
|
+
const socket2 = {
|
|
334
|
+
on: vi.fn(),
|
|
335
|
+
readyState: 1,
|
|
336
|
+
OPEN: 1,
|
|
337
|
+
send: vi.fn(),
|
|
338
|
+
close: vi.fn(),
|
|
339
|
+
};
|
|
340
|
+
await handler.handleConnection(socket1);
|
|
341
|
+
await handler.handleConnection(socket2);
|
|
342
|
+
// Subscribe socket1 to "coder"
|
|
343
|
+
messageHandler1(Buffer.from(JSON.stringify({ type: "subscribe", payload: { agentName: "coder" } })));
|
|
344
|
+
socket1.send.mockClear();
|
|
345
|
+
socket2.send.mockClear();
|
|
346
|
+
handler.broadcastToSubscribers("coder", { type: "pong" });
|
|
347
|
+
// socket1 subscribed, should receive
|
|
348
|
+
expect(socket1.send).toHaveBeenCalledWith(JSON.stringify({ type: "pong" }));
|
|
349
|
+
// socket2 not subscribed, should not receive
|
|
350
|
+
expect(socket2.send).not.toHaveBeenCalled();
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
describe("closeAll", () => {
|
|
354
|
+
it("closes all connected clients", async () => {
|
|
355
|
+
const handler = new WebSocketHandler(mockFleetManager);
|
|
356
|
+
const socket1 = {
|
|
357
|
+
on: vi.fn(),
|
|
358
|
+
readyState: 1,
|
|
359
|
+
OPEN: 1,
|
|
360
|
+
send: vi.fn(),
|
|
361
|
+
close: vi.fn(),
|
|
362
|
+
};
|
|
363
|
+
const socket2 = {
|
|
364
|
+
on: vi.fn(),
|
|
365
|
+
readyState: 1,
|
|
366
|
+
OPEN: 1,
|
|
367
|
+
send: vi.fn(),
|
|
368
|
+
close: vi.fn(),
|
|
369
|
+
};
|
|
370
|
+
await handler.handleConnection(socket1);
|
|
371
|
+
await handler.handleConnection(socket2);
|
|
372
|
+
expect(handler.getConnectedCount()).toBe(2);
|
|
373
|
+
handler.closeAll();
|
|
374
|
+
expect(socket1.close).toHaveBeenCalledWith(1000, "Server shutting down");
|
|
375
|
+
expect(socket2.close).toHaveBeenCalledWith(1000, "Server shutting down");
|
|
376
|
+
expect(handler.getConnectedCount()).toBe(0);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
//# sourceMappingURL=ws-handler.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-handler.test.js","sourceRoot":"","sources":["../../../src/server/__tests__/ws-handler.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/chat/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/chat/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,GAMf,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Chat Manager for @herdctl/web
|
|
3
|
+
*
|
|
4
|
+
* Manages chat sessions for the web platform using @herdctl/chat infrastructure.
|
|
5
|
+
* Each web session maps to a unique conversation thread with an agent.
|
|
6
|
+
*/
|
|
7
|
+
import { type FleetManager, type WebConfig } from "@herdctl/core";
|
|
8
|
+
/**
|
|
9
|
+
* Information about a web chat session
|
|
10
|
+
*/
|
|
11
|
+
export interface WebChatSession {
|
|
12
|
+
/** Unique session identifier */
|
|
13
|
+
sessionId: string;
|
|
14
|
+
/** Agent this session is for */
|
|
15
|
+
agentName: string;
|
|
16
|
+
/** ISO timestamp when the session was created */
|
|
17
|
+
createdAt: string;
|
|
18
|
+
/** ISO timestamp of the last message */
|
|
19
|
+
lastMessageAt: string;
|
|
20
|
+
/** Number of messages in this session */
|
|
21
|
+
messageCount: number;
|
|
22
|
+
/** Preview of the last message */
|
|
23
|
+
preview?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A single chat message
|
|
27
|
+
*/
|
|
28
|
+
export interface ChatMessage {
|
|
29
|
+
/** Role of the sender */
|
|
30
|
+
role: "user" | "assistant";
|
|
31
|
+
/** Message content */
|
|
32
|
+
content: string;
|
|
33
|
+
/** ISO timestamp of the message */
|
|
34
|
+
timestamp: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Session details with full message history
|
|
38
|
+
*/
|
|
39
|
+
export interface WebChatSessionDetails extends WebChatSession {
|
|
40
|
+
/** All messages in this session */
|
|
41
|
+
messages: ChatMessage[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Result of sending a message
|
|
45
|
+
*/
|
|
46
|
+
export interface SendMessageResult {
|
|
47
|
+
/** Job ID for tracking the execution */
|
|
48
|
+
jobId: string;
|
|
49
|
+
/** Whether the message was queued successfully */
|
|
50
|
+
success: boolean;
|
|
51
|
+
/** Error message if failed */
|
|
52
|
+
error?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Callback for receiving streaming chunks
|
|
56
|
+
*/
|
|
57
|
+
export type OnChunkCallback = (chunk: string) => void | Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* WebChatManager manages chat sessions for the web platform
|
|
60
|
+
*
|
|
61
|
+
* Uses ChatSessionManager from @herdctl/chat for per-agent session management.
|
|
62
|
+
* Message history is stored in JSON files at `.herdctl/web/chat-history/<agent>/<session>.json`
|
|
63
|
+
*/
|
|
64
|
+
export declare class WebChatManager {
|
|
65
|
+
private fleetManager;
|
|
66
|
+
private stateDir;
|
|
67
|
+
private sessionExpiryHours;
|
|
68
|
+
private initialized;
|
|
69
|
+
/** Per-agent session managers */
|
|
70
|
+
private sessionManagers;
|
|
71
|
+
/** In-memory session metadata cache (agentName -> sessionId -> metadata) */
|
|
72
|
+
private sessionMetadata;
|
|
73
|
+
/**
|
|
74
|
+
* Initialize the WebChatManager
|
|
75
|
+
*
|
|
76
|
+
* @param fleetManager - FleetManager instance for triggering jobs
|
|
77
|
+
* @param stateDir - State directory (e.g., ".herdctl")
|
|
78
|
+
* @param config - Web configuration from fleet config
|
|
79
|
+
*/
|
|
80
|
+
initialize(fleetManager: FleetManager, stateDir: string, config: WebConfig): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Create a new chat session for an agent
|
|
83
|
+
*
|
|
84
|
+
* @param agentName - Name of the agent
|
|
85
|
+
* @returns Session info with sessionId and createdAt
|
|
86
|
+
*/
|
|
87
|
+
createSession(agentName: string): Promise<WebChatSession>;
|
|
88
|
+
/**
|
|
89
|
+
* List all sessions for an agent
|
|
90
|
+
*
|
|
91
|
+
* @param agentName - Name of the agent
|
|
92
|
+
* @returns Array of session summaries
|
|
93
|
+
*/
|
|
94
|
+
listSessions(agentName: string): Promise<WebChatSession[]>;
|
|
95
|
+
/**
|
|
96
|
+
* Get session details with message history
|
|
97
|
+
*
|
|
98
|
+
* @param agentName - Name of the agent
|
|
99
|
+
* @param sessionId - Session ID
|
|
100
|
+
* @returns Session details with messages, or null if not found
|
|
101
|
+
*/
|
|
102
|
+
getSession(agentName: string, sessionId: string): Promise<WebChatSessionDetails | null>;
|
|
103
|
+
/**
|
|
104
|
+
* Delete a session
|
|
105
|
+
*
|
|
106
|
+
* @param agentName - Name of the agent
|
|
107
|
+
* @param sessionId - Session ID
|
|
108
|
+
* @returns true if deleted, false if not found
|
|
109
|
+
*/
|
|
110
|
+
deleteSession(agentName: string, sessionId: string): Promise<boolean>;
|
|
111
|
+
/**
|
|
112
|
+
* Send a message and trigger agent execution
|
|
113
|
+
*
|
|
114
|
+
* @param agentName - Name of the agent
|
|
115
|
+
* @param sessionId - Session ID
|
|
116
|
+
* @param message - User message text
|
|
117
|
+
* @param onChunk - Callback for streaming response chunks
|
|
118
|
+
* @returns Result with jobId
|
|
119
|
+
*/
|
|
120
|
+
sendMessage(agentName: string, sessionId: string, message: string, onChunk: OnChunkCallback): Promise<SendMessageResult>;
|
|
121
|
+
/**
|
|
122
|
+
* Ensure the manager is initialized
|
|
123
|
+
*/
|
|
124
|
+
private ensureInitialized;
|
|
125
|
+
/**
|
|
126
|
+
* Create a session manager for an agent
|
|
127
|
+
*/
|
|
128
|
+
private createSessionManagerForAgent;
|
|
129
|
+
/**
|
|
130
|
+
* Get the chat history directory path
|
|
131
|
+
*/
|
|
132
|
+
private getChatHistoryDir;
|
|
133
|
+
/**
|
|
134
|
+
* Get the message history file path for a session
|
|
135
|
+
*/
|
|
136
|
+
private getMessageHistoryPath;
|
|
137
|
+
/**
|
|
138
|
+
* Ensure chat history directories exist
|
|
139
|
+
*/
|
|
140
|
+
private ensureChatHistoryDir;
|
|
141
|
+
/**
|
|
142
|
+
* Load message history from disk
|
|
143
|
+
*/
|
|
144
|
+
private loadMessageHistory;
|
|
145
|
+
/**
|
|
146
|
+
* Save message history to disk
|
|
147
|
+
*/
|
|
148
|
+
private saveMessageHistory;
|
|
149
|
+
/**
|
|
150
|
+
* Delete message history file
|
|
151
|
+
*/
|
|
152
|
+
private deleteMessageHistory;
|
|
153
|
+
/**
|
|
154
|
+
* Load sessions from disk into metadata cache
|
|
155
|
+
*/
|
|
156
|
+
private loadSessionsFromDisk;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=web-chat-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-chat-manager.d.ts","sourceRoot":"","sources":["../../../src/server/chat/web-chat-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,SAAS,EAEf,MAAM,eAAe,CAAC;AAavB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,mCAAmC;IACnC,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAMtE;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,WAAW,CAAkB;IAErC,iCAAiC;IACjC,OAAO,CAAC,eAAe,CAA8C;IAErE,4EAA4E;IAC5E,OAAO,CAAC,eAAe,CAAuD;IAE9E;;;;;;OAMG;IACG,UAAU,CACd,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,IAAI,CAAC;IA6BhB;;;;;OAKG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA0C/D;;;;;OAKG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAoBhE;;;;;;OAMG;IACG,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAsBxC;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB3E;;;;;;;;OAQG;IACG,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,iBAAiB,CAAC;IAsH7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;YACW,4BAA4B;IA0B1C;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;OAEG;YACW,oBAAoB;IAKlC;;OAEG;YACW,kBAAkB;IAwBhC;;OAEG;YACW,kBAAkB;IAoBhC;;OAEG;YACW,oBAAoB;IAoBlC;;OAEG;YACW,oBAAoB;CA4DnC"}
|