@teneo-protocol/sdk 1.0.1 → 2.0.0
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/.github/workflows/publish-npm.yml +8 -6
- package/CHANGELOG.md +265 -0
- package/README.md +406 -53
- package/dist/core/websocket-client.d.ts +12 -0
- package/dist/core/websocket-client.d.ts.map +1 -1
- package/dist/core/websocket-client.js +22 -2
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts +76 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js +70 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts +92 -38
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +904 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js +51 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.js +65 -5
- package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-required-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.js +46 -4
- package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
- package/dist/handlers/message-handlers/challenge-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/error-message-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.d.ts +5 -0
- package/dist/handlers/message-handlers/index.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.js +23 -1
- package/dist/handlers/message-handlers/index.js.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +877 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js +38 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +886 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js +51 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +178 -89
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts +62 -58
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/regular-message-handler.d.ts +31 -29
- package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts +328 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js +92 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/types.d.ts +2 -0
- package/dist/handlers/message-handlers/types.d.ts.map +1 -1
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
- package/dist/managers/agent-room-manager.d.ts +222 -0
- package/dist/managers/agent-room-manager.d.ts.map +1 -0
- package/dist/managers/agent-room-manager.js +508 -0
- package/dist/managers/agent-room-manager.js.map +1 -0
- package/dist/managers/index.d.ts +2 -0
- package/dist/managers/index.d.ts.map +1 -1
- package/dist/managers/index.js +5 -1
- package/dist/managers/index.js.map +1 -1
- package/dist/managers/room-management-manager.d.ts +213 -0
- package/dist/managers/room-management-manager.d.ts.map +1 -0
- package/dist/managers/room-management-manager.js +440 -0
- package/dist/managers/room-management-manager.js.map +1 -0
- package/dist/managers/room-manager.d.ts +4 -4
- package/dist/managers/room-manager.d.ts.map +1 -1
- package/dist/managers/room-manager.js.map +1 -1
- package/dist/teneo-sdk.d.ts +333 -13
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +468 -1
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/config.d.ts +63 -54
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +8 -4
- package/dist/types/config.js.map +1 -1
- package/dist/types/error-codes.d.ts +2 -0
- package/dist/types/error-codes.d.ts.map +1 -1
- package/dist/types/error-codes.js +3 -0
- package/dist/types/error-codes.js.map +1 -1
- package/dist/types/events.d.ts +132 -68
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +27 -2
- package/dist/types/index.js.map +1 -1
- package/dist/types/messages.d.ts +11396 -2559
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/messages.js +294 -27
- package/dist/types/messages.js.map +1 -1
- package/examples/.env.example +1 -1
- package/examples/agent-room-management-example.ts +334 -0
- package/examples/claude-agent-x-follower/.env.example +2 -2
- package/examples/claude-agent-x-follower/QUICKSTART.md +1 -1
- package/examples/claude-agent-x-follower/README.md +1 -1
- package/examples/n8n-teneo/.env.example +2 -2
- package/examples/n8n-teneo/README.md +1 -1
- package/examples/openai-teneo/.env.example +2 -2
- package/examples/openai-teneo/README.md +1 -1
- package/examples/production-dashboard/.env.example +2 -2
- package/examples/production-dashboard/README.md +89 -12
- package/examples/production-dashboard/public/dashboard.html +1173 -601
- package/examples/production-dashboard/server.ts +347 -5
- package/examples/room-management-example.ts +285 -0
- package/examples/usage/.env.example +1 -1
- package/examples/usage/01-connect.ts +1 -1
- package/examples/usage/02-list-agents.ts +1 -1
- package/examples/usage/03-pick-agent.ts +1 -1
- package/examples/usage/04-find-by-capability.ts +1 -1
- package/examples/usage/05-webhook-example.ts +1 -1
- package/examples/usage/06-simple-api-server.ts +1 -1
- package/examples/usage/07-event-listener.ts +1 -1
- package/examples/usage/README.md +1 -1
- package/package.json +9 -1
- package/src/core/websocket-client.ts +26 -2
- package/src/handlers/message-handlers/agent-room-operation-response-handler.ts +83 -0
- package/src/handlers/message-handlers/agent-status-update-handler.ts +58 -0
- package/src/handlers/message-handlers/auth-message-handler.ts +73 -5
- package/src/handlers/message-handlers/auth-success-handler.ts +58 -6
- package/src/handlers/message-handlers/index.ts +19 -0
- package/src/handlers/message-handlers/list-available-agents-handler.ts +41 -0
- package/src/handlers/message-handlers/list-room-agents-handler.ts +61 -0
- package/src/handlers/message-handlers/room-operation-response-handler.ts +105 -0
- package/src/handlers/message-handlers/types.ts +6 -0
- package/src/managers/agent-room-manager.ts +609 -0
- package/src/managers/index.ts +2 -0
- package/src/managers/room-management-manager.ts +523 -0
- package/src/managers/room-manager.ts +4 -5
- package/src/teneo-sdk.ts +505 -4
- package/src/types/config.ts +10 -5
- package/src/types/error-codes.ts +4 -0
- package/src/types/events.ts +24 -0
- package/src/types/index.ts +55 -0
- package/src/types/messages.ts +374 -41
- package/tests/integration/room-management.test.ts +514 -0
- package/tests/integration/websocket.test.ts +1 -1
- package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +394 -0
- package/tests/unit/handlers/agent-status-update-handler.test.ts +407 -0
- package/tests/unit/handlers/auth-success-handler-rooms.test.ts +699 -0
- package/tests/unit/handlers/list-available-agents-handler.test.ts +256 -0
- package/tests/unit/handlers/list-room-agents-handler.test.ts +294 -0
- package/tests/unit/handlers/room-operation-response-handler.test.ts +527 -0
- package/tests/unit/managers/agent-room-manager.test.ts +534 -0
- package/tests/unit/managers/room-management-manager.test.ts +438 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for AgentStatusUpdateHandler
|
|
3
|
+
* Tests real-time agent status update handling and cache invalidation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
7
|
+
import { AgentStatusUpdateHandler } from "../../../src/handlers/message-handlers/agent-status-update-handler";
|
|
8
|
+
import { HandlerContext } from "../../../src/handlers/message-handlers/types";
|
|
9
|
+
import { Logger } from "../../../src/types";
|
|
10
|
+
|
|
11
|
+
describe("AgentStatusUpdateHandler", () => {
|
|
12
|
+
let handler: AgentStatusUpdateHandler;
|
|
13
|
+
let mockContext: HandlerContext;
|
|
14
|
+
let mockLogger: Logger;
|
|
15
|
+
let mockAgentRoomManager: any;
|
|
16
|
+
let emitSpy: ReturnType<typeof vi.fn>;
|
|
17
|
+
let sendWebhookSpy: ReturnType<typeof vi.fn>;
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
// Create mock logger
|
|
21
|
+
mockLogger = {
|
|
22
|
+
debug: vi.fn(),
|
|
23
|
+
info: vi.fn(),
|
|
24
|
+
warn: vi.fn(),
|
|
25
|
+
error: vi.fn()
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Create mock agent room manager
|
|
29
|
+
mockAgentRoomManager = {
|
|
30
|
+
handleStatusUpdate: vi.fn()
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Create spies
|
|
34
|
+
emitSpy = vi.fn();
|
|
35
|
+
sendWebhookSpy = vi.fn().mockResolvedValue(undefined);
|
|
36
|
+
|
|
37
|
+
// Create mock context
|
|
38
|
+
mockContext = {
|
|
39
|
+
emit: emitSpy,
|
|
40
|
+
sendWebhook: sendWebhookSpy,
|
|
41
|
+
logger: mockLogger,
|
|
42
|
+
getConnectionState: vi.fn(),
|
|
43
|
+
getAuthState: vi.fn(),
|
|
44
|
+
updateConnectionState: vi.fn(),
|
|
45
|
+
updateAuthState: vi.fn(),
|
|
46
|
+
sendMessage: vi.fn(),
|
|
47
|
+
agentRoomManager: mockAgentRoomManager
|
|
48
|
+
} as any;
|
|
49
|
+
|
|
50
|
+
// Create handler instance
|
|
51
|
+
handler = new AgentStatusUpdateHandler();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe("Handler Metadata", () => {
|
|
55
|
+
it("should have correct type", () => {
|
|
56
|
+
expect(handler.type).toBe("agent_status_update");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("should have schema defined", () => {
|
|
60
|
+
expect(handler.schema).toBeDefined();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should identify messages it can handle", () => {
|
|
64
|
+
const message = { type: "agent_status_update", data: {} };
|
|
65
|
+
expect(handler.canHandle(message as any)).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should not handle other message types", () => {
|
|
69
|
+
const message = { type: "other_type", data: {} };
|
|
70
|
+
expect(handler.canHandle(message as any)).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe("Status Update Handling", () => {
|
|
75
|
+
it("should handle agent status update", async () => {
|
|
76
|
+
const message = {
|
|
77
|
+
type: "agent_status_update" as const,
|
|
78
|
+
data: {
|
|
79
|
+
room_id: "room-123",
|
|
80
|
+
agent_id: "agent-456",
|
|
81
|
+
status: "offline"
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
await handler.handle(message, mockContext);
|
|
86
|
+
|
|
87
|
+
// Should invalidate cache via agent room manager
|
|
88
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenCalledWith(
|
|
89
|
+
"room-123",
|
|
90
|
+
"agent-456",
|
|
91
|
+
"offline"
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Should emit event
|
|
95
|
+
expect(emitSpy).toHaveBeenCalledWith("agent_room:status_update", {
|
|
96
|
+
roomId: "room-123",
|
|
97
|
+
agentId: "agent-456",
|
|
98
|
+
status: "offline",
|
|
99
|
+
agent: undefined
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Should send webhook
|
|
103
|
+
expect(sendWebhookSpy).toHaveBeenCalledWith(
|
|
104
|
+
"agent_status_update",
|
|
105
|
+
expect.objectContaining({
|
|
106
|
+
room_id: "room-123",
|
|
107
|
+
agent_id: "agent-456",
|
|
108
|
+
status: "offline"
|
|
109
|
+
}),
|
|
110
|
+
undefined
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
// Should log
|
|
114
|
+
expect(mockLogger.info).toHaveBeenCalledWith(
|
|
115
|
+
"Agent status updated",
|
|
116
|
+
expect.objectContaining({
|
|
117
|
+
roomId: "room-123",
|
|
118
|
+
agentId: "agent-456",
|
|
119
|
+
status: "offline"
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("should handle status update with agent details", async () => {
|
|
125
|
+
const agentDetails = {
|
|
126
|
+
agent_id: "agent-456",
|
|
127
|
+
agent_name: "Weather Agent",
|
|
128
|
+
description: "Provides weather info",
|
|
129
|
+
status: "online"
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const message = {
|
|
133
|
+
type: "agent_status_update" as const,
|
|
134
|
+
data: {
|
|
135
|
+
room_id: "room-123",
|
|
136
|
+
agent_id: "agent-456",
|
|
137
|
+
status: "online",
|
|
138
|
+
agent: agentDetails
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
await handler.handle(message, mockContext);
|
|
143
|
+
|
|
144
|
+
// Should emit event with agent details
|
|
145
|
+
expect(emitSpy).toHaveBeenCalledWith("agent_room:status_update", {
|
|
146
|
+
roomId: "room-123",
|
|
147
|
+
agentId: "agent-456",
|
|
148
|
+
status: "online",
|
|
149
|
+
agent: agentDetails
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("should handle online status", async () => {
|
|
154
|
+
const message = {
|
|
155
|
+
type: "agent_status_update" as const,
|
|
156
|
+
data: {
|
|
157
|
+
room_id: "room-789",
|
|
158
|
+
agent_id: "agent-999",
|
|
159
|
+
status: "online"
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
await handler.handle(message, mockContext);
|
|
164
|
+
|
|
165
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenCalledWith(
|
|
166
|
+
"room-789",
|
|
167
|
+
"agent-999",
|
|
168
|
+
"online"
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("should work without agentRoomManager in context", async () => {
|
|
173
|
+
const contextWithoutManager = { ...mockContext, agentRoomManager: undefined };
|
|
174
|
+
|
|
175
|
+
const message = {
|
|
176
|
+
type: "agent_status_update" as const,
|
|
177
|
+
data: {
|
|
178
|
+
room_id: "room-123",
|
|
179
|
+
agent_id: "agent-456",
|
|
180
|
+
status: "offline"
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
await handler.handle(message, contextWithoutManager);
|
|
185
|
+
|
|
186
|
+
// Should still emit event
|
|
187
|
+
expect(emitSpy).toHaveBeenCalledWith("agent_room:status_update", {
|
|
188
|
+
roomId: "room-123",
|
|
189
|
+
agentId: "agent-456",
|
|
190
|
+
status: "offline",
|
|
191
|
+
agent: undefined
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("should work with agentRoomManager without handleStatusUpdate method", async () => {
|
|
196
|
+
const invalidManager = { someOtherMethod: vi.fn() };
|
|
197
|
+
const contextWithInvalidManager = {
|
|
198
|
+
...mockContext,
|
|
199
|
+
agentRoomManager: invalidManager
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const message = {
|
|
203
|
+
type: "agent_status_update" as const,
|
|
204
|
+
data: {
|
|
205
|
+
room_id: "room-123",
|
|
206
|
+
agent_id: "agent-456",
|
|
207
|
+
status: "offline"
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Should not throw
|
|
212
|
+
await handler.handle(message, contextWithInvalidManager);
|
|
213
|
+
|
|
214
|
+
// Should still emit event
|
|
215
|
+
expect(emitSpy).toHaveBeenCalledWith("agent_room:status_update", {
|
|
216
|
+
roomId: "room-123",
|
|
217
|
+
agentId: "agent-456",
|
|
218
|
+
status: "offline",
|
|
219
|
+
agent: undefined
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("Webhook Errors", () => {
|
|
225
|
+
it("should handle webhook failures gracefully", async () => {
|
|
226
|
+
const webhookError = new Error("Webhook failed");
|
|
227
|
+
sendWebhookSpy.mockRejectedValueOnce(webhookError);
|
|
228
|
+
|
|
229
|
+
const message = {
|
|
230
|
+
type: "agent_status_update" as const,
|
|
231
|
+
data: {
|
|
232
|
+
room_id: "room-123",
|
|
233
|
+
agent_id: "agent-456",
|
|
234
|
+
status: "offline"
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// Should not throw
|
|
239
|
+
await handler.handle(message, mockContext);
|
|
240
|
+
|
|
241
|
+
// Should still emit event and invalidate cache
|
|
242
|
+
expect(emitSpy).toHaveBeenCalledWith("agent_room:status_update", expect.any(Object));
|
|
243
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenCalled();
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
describe("Message Validation", () => {
|
|
248
|
+
it("should handle invalid message structure", async () => {
|
|
249
|
+
const invalidMessage = {
|
|
250
|
+
type: "agent_status_update",
|
|
251
|
+
// Missing data field
|
|
252
|
+
} as any;
|
|
253
|
+
|
|
254
|
+
await handler.handle(invalidMessage, mockContext);
|
|
255
|
+
|
|
256
|
+
// Should log error
|
|
257
|
+
expect(mockLogger.error).toHaveBeenCalledWith(
|
|
258
|
+
expect.stringContaining("Error handling agent_status_update"),
|
|
259
|
+
expect.any(Error)
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
// Should emit message:error event
|
|
263
|
+
expect(emitSpy).toHaveBeenCalledWith(
|
|
264
|
+
"message:error",
|
|
265
|
+
expect.any(Error),
|
|
266
|
+
invalidMessage
|
|
267
|
+
);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("should accept valid message with extra fields", async () => {
|
|
271
|
+
const message = {
|
|
272
|
+
type: "agent_status_update" as const,
|
|
273
|
+
data: {
|
|
274
|
+
room_id: "room-123",
|
|
275
|
+
agent_id: "agent-456",
|
|
276
|
+
status: "online",
|
|
277
|
+
extra_field: "should be ignored",
|
|
278
|
+
another_extra: 123
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// Should not throw
|
|
283
|
+
await handler.handle(message, mockContext);
|
|
284
|
+
|
|
285
|
+
expect(emitSpy).toHaveBeenCalledWith("agent_room:status_update", expect.any(Object));
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
describe("Debug Logging", () => {
|
|
290
|
+
it("should log debug info", async () => {
|
|
291
|
+
const message = {
|
|
292
|
+
type: "agent_status_update" as const,
|
|
293
|
+
data: {
|
|
294
|
+
room_id: "room-123",
|
|
295
|
+
agent_id: "agent-456",
|
|
296
|
+
status: "offline"
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
await handler.handle(message, mockContext);
|
|
301
|
+
|
|
302
|
+
expect(mockLogger.debug).toHaveBeenCalledWith(
|
|
303
|
+
"Handling agent_status_update",
|
|
304
|
+
expect.objectContaining({
|
|
305
|
+
roomId: "room-123",
|
|
306
|
+
agentId: "agent-456",
|
|
307
|
+
status: "offline"
|
|
308
|
+
})
|
|
309
|
+
);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it("should log debug info with agent details", async () => {
|
|
313
|
+
const message = {
|
|
314
|
+
type: "agent_status_update" as const,
|
|
315
|
+
data: {
|
|
316
|
+
room_id: "room-123",
|
|
317
|
+
agent_id: "agent-456",
|
|
318
|
+
status: "online",
|
|
319
|
+
agent: {
|
|
320
|
+
agent_id: "agent-456",
|
|
321
|
+
agent_name: "Test Agent"
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
await handler.handle(message, mockContext);
|
|
327
|
+
|
|
328
|
+
expect(mockLogger.debug).toHaveBeenCalledWith(
|
|
329
|
+
"Handling agent_status_update",
|
|
330
|
+
expect.objectContaining({
|
|
331
|
+
roomId: "room-123",
|
|
332
|
+
agentId: "agent-456",
|
|
333
|
+
status: "online",
|
|
334
|
+
hasAgent: true
|
|
335
|
+
})
|
|
336
|
+
);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
describe("Multiple Status Updates", () => {
|
|
341
|
+
it("should handle multiple status updates for different agents", async () => {
|
|
342
|
+
const message1 = {
|
|
343
|
+
type: "agent_status_update" as const,
|
|
344
|
+
data: {
|
|
345
|
+
room_id: "room-123",
|
|
346
|
+
agent_id: "agent-1",
|
|
347
|
+
status: "offline"
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const message2 = {
|
|
352
|
+
type: "agent_status_update" as const,
|
|
353
|
+
data: {
|
|
354
|
+
room_id: "room-123",
|
|
355
|
+
agent_id: "agent-2",
|
|
356
|
+
status: "online"
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
await handler.handle(message1, mockContext);
|
|
361
|
+
await handler.handle(message2, mockContext);
|
|
362
|
+
|
|
363
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenCalledTimes(2);
|
|
364
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenCalledWith(
|
|
365
|
+
"room-123",
|
|
366
|
+
"agent-1",
|
|
367
|
+
"offline"
|
|
368
|
+
);
|
|
369
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenCalledWith(
|
|
370
|
+
"room-123",
|
|
371
|
+
"agent-2",
|
|
372
|
+
"online"
|
|
373
|
+
);
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
it("should handle multiple status updates for same agent", async () => {
|
|
377
|
+
const message1 = {
|
|
378
|
+
type: "agent_status_update" as const,
|
|
379
|
+
data: {
|
|
380
|
+
room_id: "room-123",
|
|
381
|
+
agent_id: "agent-1",
|
|
382
|
+
status: "online"
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
const message2 = {
|
|
387
|
+
type: "agent_status_update" as const,
|
|
388
|
+
data: {
|
|
389
|
+
room_id: "room-123",
|
|
390
|
+
agent_id: "agent-1",
|
|
391
|
+
status: "offline"
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
await handler.handle(message1, mockContext);
|
|
396
|
+
await handler.handle(message2, mockContext);
|
|
397
|
+
|
|
398
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenCalledTimes(2);
|
|
399
|
+
// Last call should be offline
|
|
400
|
+
expect(mockAgentRoomManager.handleStatusUpdate).toHaveBeenLastCalledWith(
|
|
401
|
+
"room-123",
|
|
402
|
+
"agent-1",
|
|
403
|
+
"offline"
|
|
404
|
+
);
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
});
|