@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
|
@@ -15,7 +15,7 @@ import { TeneoSDK, SDKConfigBuilder } from "../../dist/index.js";
|
|
|
15
15
|
|
|
16
16
|
// Load configuration from environment
|
|
17
17
|
const WS_URL =
|
|
18
|
-
process.env.WS_URL || "wss://
|
|
18
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
19
19
|
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
20
20
|
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
21
21
|
|
|
@@ -15,7 +15,7 @@ import { TeneoSDK, SDKConfigBuilder } from "../../dist/index.js";
|
|
|
15
15
|
|
|
16
16
|
// Load configuration from environment
|
|
17
17
|
const WS_URL =
|
|
18
|
-
process.env.WS_URL || "wss://
|
|
18
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
19
19
|
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
20
20
|
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
21
21
|
|
|
@@ -16,7 +16,7 @@ import { TeneoSDK, SDKConfigBuilder, FormattedResponse } from "../../dist/index.
|
|
|
16
16
|
|
|
17
17
|
// Load configuration from environment
|
|
18
18
|
const WS_URL =
|
|
19
|
-
process.env.WS_URL || "wss://
|
|
19
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
20
20
|
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
21
21
|
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
22
22
|
|
|
@@ -16,7 +16,7 @@ import { TeneoSDK, SDKConfigBuilder } from "../../dist/index.js";
|
|
|
16
16
|
|
|
17
17
|
// Load configuration from environment
|
|
18
18
|
const WS_URL =
|
|
19
|
-
process.env.WS_URL || "wss://
|
|
19
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
20
20
|
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
21
21
|
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
22
22
|
|
|
@@ -27,7 +27,7 @@ import type { Request, Response } from "express";
|
|
|
27
27
|
|
|
28
28
|
// Load configuration from environment
|
|
29
29
|
const WS_URL =
|
|
30
|
-
process.env.WS_URL || "wss://
|
|
30
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
31
31
|
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
32
32
|
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
33
33
|
const WEBHOOK_PORT = parseInt(process.env.WEBHOOK_PORT || "3001");
|
|
@@ -22,7 +22,7 @@ import { TeneoSDK, SDKConfigBuilder } from "../../dist/index.js";
|
|
|
22
22
|
|
|
23
23
|
// Load configuration from environment
|
|
24
24
|
const WS_URL =
|
|
25
|
-
process.env.WS_URL || "wss://
|
|
25
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
26
26
|
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
27
27
|
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
28
28
|
const PORT = parseInt(process.env.PORT || "3000");
|
|
@@ -16,7 +16,7 @@ import { TeneoSDK, SDKConfigBuilder } from "../../dist/index.js";
|
|
|
16
16
|
|
|
17
17
|
// Load configuration from environment
|
|
18
18
|
const WS_URL =
|
|
19
|
-
process.env.WS_URL || "wss://
|
|
19
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
20
20
|
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
21
21
|
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
22
22
|
|
package/examples/usage/README.md
CHANGED
|
@@ -29,7 +29,7 @@ Create a `.env` file in the project root or export these variables:
|
|
|
29
29
|
```bash
|
|
30
30
|
# Required
|
|
31
31
|
PRIVATE_KEY=your_ethereum_private_key_here
|
|
32
|
-
WS_URL=wss://
|
|
32
|
+
WS_URL=wss://your-teneo-server.com/ws
|
|
33
33
|
|
|
34
34
|
# Optional
|
|
35
35
|
DEFAULT_ROOM=general
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teneo-protocol/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "TypeScript SDK for external platforms to interact with Teneo agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,6 +15,14 @@
|
|
|
15
15
|
],
|
|
16
16
|
"author": "Teneo Protocol",
|
|
17
17
|
"license": "AGPL-3.0",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/TeneoProtocolAI/teneo-sdk.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/TeneoProtocolAI/teneo-sdk/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/TeneoProtocolAI/teneo-sdk#readme",
|
|
18
26
|
"dependencies": {
|
|
19
27
|
"eventemitter3": "^5.0.1",
|
|
20
28
|
"node-fetch": "^3.3.2",
|
|
@@ -56,6 +56,8 @@ export class WebSocketClient extends EventEmitter<SDKEvents> {
|
|
|
56
56
|
private deduplicationCache?: DeduplicationCache;
|
|
57
57
|
private reconnectPolicy: RetryPolicy;
|
|
58
58
|
private roomManager?: any; // Reference to RoomManager for handler context
|
|
59
|
+
private roomManagementManager?: any; // Reference to RoomManagementManager for handler context (v2.0.0)
|
|
60
|
+
private agentRoomManager?: any; // Reference to AgentRoomManager for handler context (v2.0.0)
|
|
59
61
|
private intentionalDisconnect: boolean = false; // Track intentional disconnect to prevent reconnection
|
|
60
62
|
|
|
61
63
|
private connectionState: ConnectionState = {
|
|
@@ -211,6 +213,22 @@ export class WebSocketClient extends EventEmitter<SDKEvents> {
|
|
|
211
213
|
this.roomManager = roomManager;
|
|
212
214
|
}
|
|
213
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Sets the room management manager for room CRUD operations (v2.0.0)
|
|
218
|
+
* @internal
|
|
219
|
+
*/
|
|
220
|
+
public setRoomManagementManager(roomManagementManager: any): void {
|
|
221
|
+
this.roomManagementManager = roomManagementManager;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Sets the agent room manager for agent-room operations (v2.0.0)
|
|
226
|
+
* @internal
|
|
227
|
+
*/
|
|
228
|
+
public setAgentRoomManager(agentRoomManager: any): void {
|
|
229
|
+
this.agentRoomManager = agentRoomManager;
|
|
230
|
+
}
|
|
231
|
+
|
|
214
232
|
/**
|
|
215
233
|
* Establishes a WebSocket connection to the Teneo server.
|
|
216
234
|
* Handles connection timeout, authentication challenge-response flow,
|
|
@@ -296,7 +314,11 @@ export class WebSocketClient extends EventEmitter<SDKEvents> {
|
|
|
296
314
|
if (parseResult.success) {
|
|
297
315
|
this.handleMessage(parseResult.data as BaseMessage);
|
|
298
316
|
} else {
|
|
299
|
-
|
|
317
|
+
// Use warn instead of error - allows SDK to be more resilient
|
|
318
|
+
this.logger.warn("Received message with unknown or invalid format", {
|
|
319
|
+
type: rawMessage?.type,
|
|
320
|
+
error: parseResult.error?.message
|
|
321
|
+
});
|
|
300
322
|
this.emit(
|
|
301
323
|
"message:error",
|
|
302
324
|
new ValidationError("Invalid message format", parseResult.error),
|
|
@@ -494,7 +516,7 @@ export class WebSocketClient extends EventEmitter<SDKEvents> {
|
|
|
494
516
|
this.logger.error("Failed to send message", error);
|
|
495
517
|
reject(error);
|
|
496
518
|
} else {
|
|
497
|
-
this.logger.debug("Message sent",
|
|
519
|
+
this.logger.debug("Message sent", validatedMessage);
|
|
498
520
|
this.emit("message:sent", validatedMessage);
|
|
499
521
|
resolve();
|
|
500
522
|
}
|
|
@@ -653,6 +675,8 @@ export class WebSocketClient extends EventEmitter<SDKEvents> {
|
|
|
653
675
|
updateConnectionState: (update: any) => this.updateConnectionState(update),
|
|
654
676
|
updateAuthState: (update: any) => this.updateAuthState(update),
|
|
655
677
|
roomManager: this.roomManager,
|
|
678
|
+
roomManagementManager: this.roomManagementManager,
|
|
679
|
+
agentRoomManager: this.agentRoomManager,
|
|
656
680
|
account: this.account,
|
|
657
681
|
sendMessage: (message: BaseMessage) => this.sendMessage(message)
|
|
658
682
|
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler for agent_room_operation_response messages (v2.0.0)
|
|
3
|
+
* Processes responses from agent-room operations (add, remove)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
AgentRoomOperationResponse,
|
|
8
|
+
AgentRoomOperationResponseSchema
|
|
9
|
+
} from "../../types";
|
|
10
|
+
import { BaseMessageHandler } from "./base-handler";
|
|
11
|
+
import { HandlerContext } from "./types";
|
|
12
|
+
import { SDKError } from "../../types/events";
|
|
13
|
+
import { ErrorCode } from "../../types/error-codes";
|
|
14
|
+
|
|
15
|
+
export class AgentRoomOperationResponseHandler extends BaseMessageHandler<AgentRoomOperationResponse> {
|
|
16
|
+
readonly type = "agent_room_operation_response" as const;
|
|
17
|
+
readonly schema = AgentRoomOperationResponseSchema;
|
|
18
|
+
|
|
19
|
+
protected handleValidated(
|
|
20
|
+
message: AgentRoomOperationResponse,
|
|
21
|
+
context: HandlerContext
|
|
22
|
+
): void {
|
|
23
|
+
const { success, message: errorMessage, room_id, agent_id } = message.data;
|
|
24
|
+
|
|
25
|
+
context.logger.debug("Handling agent_room_operation_response", {
|
|
26
|
+
success,
|
|
27
|
+
roomId: room_id,
|
|
28
|
+
agentId: agent_id
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (!success) {
|
|
32
|
+
// Operation failed - emit error events
|
|
33
|
+
const error = new SDKError(
|
|
34
|
+
errorMessage || "Agent room operation failed",
|
|
35
|
+
ErrorCode.OPERATION_FAILED
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
context.logger.error("Agent room operation failed", {
|
|
39
|
+
roomId: room_id,
|
|
40
|
+
agentId: agent_id,
|
|
41
|
+
error: errorMessage
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Emit both add and remove error events - listeners will filter by room/agent ID
|
|
45
|
+
this.emit(context, "agent_room:add_error", error, room_id);
|
|
46
|
+
this.emit(context, "agent_room:remove_error", error, room_id);
|
|
47
|
+
|
|
48
|
+
// Send webhook
|
|
49
|
+
this.sendWebhook(context, "agent_room_operation_error", {
|
|
50
|
+
success: false,
|
|
51
|
+
message: errorMessage,
|
|
52
|
+
room_id,
|
|
53
|
+
agent_id
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Operation succeeded
|
|
60
|
+
if (room_id && agent_id) {
|
|
61
|
+
context.logger.info("Agent room operation succeeded", {
|
|
62
|
+
roomId: room_id,
|
|
63
|
+
agentId: agent_id
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Emit success events
|
|
67
|
+
// The promise handlers in AgentRoomManager will filter by room_id and agent_id
|
|
68
|
+
this.emit(context, "agent_room:agent_added", room_id, agent_id);
|
|
69
|
+
this.emit(context, "agent_room:agent_removed", room_id, agent_id);
|
|
70
|
+
|
|
71
|
+
// Send webhook
|
|
72
|
+
this.sendWebhook(context, "agent_room_operation", {
|
|
73
|
+
success: true,
|
|
74
|
+
room_id,
|
|
75
|
+
agent_id,
|
|
76
|
+
message: "Agent room operation completed successfully"
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
// Unexpected: success but missing required fields
|
|
80
|
+
context.logger.warn("Agent room operation succeeded but missing room_id or agent_id");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler for agent_status_update messages (v2.0.0)
|
|
3
|
+
* Processes real-time agent status updates for rooms
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
AgentStatusUpdateMessage,
|
|
8
|
+
AgentStatusUpdateMessageSchema
|
|
9
|
+
} from "../../types";
|
|
10
|
+
import { BaseMessageHandler } from "./base-handler";
|
|
11
|
+
import { HandlerContext } from "./types";
|
|
12
|
+
|
|
13
|
+
export class AgentStatusUpdateHandler extends BaseMessageHandler<AgentStatusUpdateMessage> {
|
|
14
|
+
readonly type = "agent_status_update" as const;
|
|
15
|
+
readonly schema = AgentStatusUpdateMessageSchema;
|
|
16
|
+
|
|
17
|
+
protected handleValidated(
|
|
18
|
+
message: AgentStatusUpdateMessage,
|
|
19
|
+
context: HandlerContext
|
|
20
|
+
): void {
|
|
21
|
+
const { room_id, agent_id, status, agent } = message.data;
|
|
22
|
+
|
|
23
|
+
context.logger.debug("Handling agent_status_update", {
|
|
24
|
+
roomId: room_id,
|
|
25
|
+
agentId: agent_id,
|
|
26
|
+
status,
|
|
27
|
+
hasAgent: !!agent
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Invalidate cache for this room via agent room manager
|
|
31
|
+
const agentRoomManager = (context as any).agentRoomManager;
|
|
32
|
+
if (agentRoomManager && typeof agentRoomManager.handleStatusUpdate === "function") {
|
|
33
|
+
agentRoomManager.handleStatusUpdate(room_id, agent_id, status);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
context.logger.info("Agent status updated", {
|
|
37
|
+
roomId: room_id,
|
|
38
|
+
agentId: agent_id,
|
|
39
|
+
status
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Emit status update event
|
|
43
|
+
this.emit(context, "agent_room:status_update", {
|
|
44
|
+
roomId: room_id,
|
|
45
|
+
agentId: agent_id,
|
|
46
|
+
status,
|
|
47
|
+
agent
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Send webhook
|
|
51
|
+
this.sendWebhook(context, "agent_status_update", {
|
|
52
|
+
room_id,
|
|
53
|
+
agent_id,
|
|
54
|
+
status,
|
|
55
|
+
agent
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -26,8 +26,27 @@ export class AuthMessageHandler extends BaseMessageHandler<AuthMessage> {
|
|
|
26
26
|
isCachedAuth ? "Using cached authentication" : "Authentication successful"
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
-
// Extract rooms
|
|
30
|
-
const
|
|
29
|
+
// Extract rooms from both 'rooms' (public) and 'private_rooms' (owned private) arrays
|
|
30
|
+
const publicRooms = this.extractRooms(message.data?.rooms);
|
|
31
|
+
const privateRooms = this.extractRooms(message.data?.private_rooms);
|
|
32
|
+
|
|
33
|
+
// Combine all rooms, ensuring correct ownership flags
|
|
34
|
+
// Public rooms from 'rooms' array are NOT owned by the user
|
|
35
|
+
// Private rooms from 'private_rooms' array ARE owned by the user
|
|
36
|
+
const allRooms = [
|
|
37
|
+
...publicRooms.map((r) => ({
|
|
38
|
+
...r,
|
|
39
|
+
is_owner: false, // Explicitly set to false - public rooms are not owned
|
|
40
|
+
is_public: r.is_public !== undefined ? r.is_public : true // Ensure is_public is set
|
|
41
|
+
})),
|
|
42
|
+
...privateRooms.map((r) => ({
|
|
43
|
+
...r,
|
|
44
|
+
is_owner: true, // Explicitly set to true - private_rooms array means owned
|
|
45
|
+
is_public: r.is_public !== undefined ? r.is_public : false // Ensure is_public is set
|
|
46
|
+
}))
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
const { privateRoomIds, sharedRoomIds } = this.categorizeRooms(allRooms);
|
|
31
50
|
|
|
32
51
|
// Update connection state
|
|
33
52
|
this.updateConnectionState(context, { authenticated: true });
|
|
@@ -40,11 +59,37 @@ export class AuthMessageHandler extends BaseMessageHandler<AuthMessage> {
|
|
|
40
59
|
isWhitelisted: message.data?.is_whitelisted,
|
|
41
60
|
isAdmin: message.data?.is_admin_whitelisted,
|
|
42
61
|
nftVerified: message.data?.nft_verified,
|
|
43
|
-
rooms:
|
|
44
|
-
roomObjects:
|
|
45
|
-
privateRoomId: message.data?.private_room_id
|
|
62
|
+
rooms: allRooms.map((r) => r.id),
|
|
63
|
+
roomObjects: allRooms,
|
|
64
|
+
privateRoomId: message.data?.private_room_id,
|
|
65
|
+
// v2.0.0: New fields
|
|
66
|
+
privateRoomIds, // Rooms user owns
|
|
67
|
+
sharedRoomIds, // Rooms user is member of
|
|
68
|
+
maxPrivateRooms: message.data?.max_private_rooms // Max rooms user can create
|
|
46
69
|
});
|
|
47
70
|
|
|
71
|
+
// Initialize room management manager with room data (v2.0.0)
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
+
const roomMgmt = (context as any).roomManagementManager;
|
|
74
|
+
if (roomMgmt) {
|
|
75
|
+
// Set room limit
|
|
76
|
+
if (message.data?.max_private_rooms) {
|
|
77
|
+
roomMgmt.setRoomLimit(message.data.max_private_rooms);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Categorize and cache rooms
|
|
81
|
+
const ownedRooms = allRooms.filter((r) => r.is_owner === true);
|
|
82
|
+
const sharedRooms = allRooms.filter((r) => r.is_owner === false);
|
|
83
|
+
roomMgmt.setOwnedRooms(ownedRooms);
|
|
84
|
+
roomMgmt.setSharedRooms(sharedRooms);
|
|
85
|
+
|
|
86
|
+
context.logger.debug("Room management initialized from auth message", {
|
|
87
|
+
owned: ownedRooms.length,
|
|
88
|
+
shared: sharedRooms.length,
|
|
89
|
+
limit: message.data?.max_private_rooms
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
48
93
|
// Get updated auth state
|
|
49
94
|
const authState = context.getAuthState();
|
|
50
95
|
|
|
@@ -63,4 +108,27 @@ export class AuthMessageHandler extends BaseMessageHandler<AuthMessage> {
|
|
|
63
108
|
}
|
|
64
109
|
return rooms;
|
|
65
110
|
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Categorize rooms into owned vs member rooms based on is_owner flag
|
|
114
|
+
* @param rooms - Array of room info objects
|
|
115
|
+
* @returns Object with privateRoomIds (owned) and sharedRoomIds (member)
|
|
116
|
+
*/
|
|
117
|
+
private categorizeRooms(rooms: Room[]): {
|
|
118
|
+
privateRoomIds: string[];
|
|
119
|
+
sharedRoomIds: string[];
|
|
120
|
+
} {
|
|
121
|
+
const privateRoomIds: string[] = [];
|
|
122
|
+
const sharedRoomIds: string[] = [];
|
|
123
|
+
|
|
124
|
+
for (const room of rooms) {
|
|
125
|
+
if (room.is_owner) {
|
|
126
|
+
if (room.id) privateRoomIds.push(room.id);
|
|
127
|
+
} else {
|
|
128
|
+
if (room.id) sharedRoomIds.push(room.id);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return { privateRoomIds, sharedRoomIds };
|
|
133
|
+
}
|
|
66
134
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import { AuthSuccessMessage, AuthSuccessMessageSchema,
|
|
7
|
+
import { AuthSuccessMessage, AuthSuccessMessageSchema, RoomInfo } from "../../types";
|
|
8
8
|
import { BaseMessageHandler } from "./base-handler";
|
|
9
9
|
import { HandlerContext } from "./types";
|
|
10
10
|
|
|
@@ -18,8 +18,9 @@ export class AuthSuccessHandler extends BaseMessageHandler<AuthSuccessMessage> {
|
|
|
18
18
|
): Promise<void> {
|
|
19
19
|
context.logger.info("Authentication successful");
|
|
20
20
|
|
|
21
|
-
// Extract rooms
|
|
21
|
+
// Extract and categorize rooms
|
|
22
22
|
const rooms = this.extractRooms(message.data.rooms);
|
|
23
|
+
const { privateRoomIds, sharedRoomIds } = this.categorizeRooms(rooms);
|
|
23
24
|
|
|
24
25
|
// Update connection state
|
|
25
26
|
this.updateConnectionState(context, { authenticated: true });
|
|
@@ -32,14 +33,42 @@ export class AuthSuccessHandler extends BaseMessageHandler<AuthSuccessMessage> {
|
|
|
32
33
|
isWhitelisted: message.data.is_whitelisted,
|
|
33
34
|
isAdmin: message.data.is_admin_whitelisted,
|
|
34
35
|
nftVerified: message.data.nft_verified,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
|
|
37
|
+
// Backward compatibility: deprecated fields
|
|
38
|
+
rooms: rooms.map((r) => r.id), // All room IDs
|
|
39
|
+
privateRoomId: message.data.private_room_id, // DEPRECATED: single private room ID
|
|
40
|
+
|
|
41
|
+
// v2.0.0: New fields
|
|
42
|
+
roomObjects: rooms, // Full room objects with is_owner field
|
|
43
|
+
privateRoomIds, // Rooms user owns
|
|
44
|
+
sharedRoomIds, // Rooms user is member of
|
|
45
|
+
maxPrivateRooms: message.data.max_private_rooms // Max rooms user can create
|
|
38
46
|
});
|
|
39
47
|
|
|
40
48
|
// Get updated auth state
|
|
41
49
|
const authState = context.getAuthState();
|
|
42
50
|
|
|
51
|
+
// Initialize room management manager with room data (v2.0.0)
|
|
52
|
+
const roomMgmt = (context as any).roomManagementManager;
|
|
53
|
+
if (roomMgmt) {
|
|
54
|
+
// Set room limit
|
|
55
|
+
if (message.data.max_private_rooms) {
|
|
56
|
+
roomMgmt.setRoomLimit(message.data.max_private_rooms);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Categorize and cache rooms
|
|
60
|
+
const ownedRooms = rooms.filter((r) => r.is_owner);
|
|
61
|
+
const sharedRooms = rooms.filter((r) => !r.is_owner);
|
|
62
|
+
roomMgmt.setOwnedRooms(ownedRooms);
|
|
63
|
+
roomMgmt.setSharedRooms(sharedRooms);
|
|
64
|
+
|
|
65
|
+
context.logger.debug("Room management initialized", {
|
|
66
|
+
owned: ownedRooms.length,
|
|
67
|
+
shared: sharedRooms.length,
|
|
68
|
+
limit: message.data.max_private_rooms
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
43
72
|
// Emit events
|
|
44
73
|
this.emit(context, "auth:success", authState);
|
|
45
74
|
this.emit(context, "ready");
|
|
@@ -48,10 +77,33 @@ export class AuthSuccessHandler extends BaseMessageHandler<AuthSuccessMessage> {
|
|
|
48
77
|
/**
|
|
49
78
|
* Extract and normalize rooms from auth data
|
|
50
79
|
*/
|
|
51
|
-
private extractRooms(rooms?:
|
|
80
|
+
private extractRooms(rooms?: RoomInfo[] | null): RoomInfo[] {
|
|
52
81
|
if (!rooms || !Array.isArray(rooms)) {
|
|
53
82
|
return [];
|
|
54
83
|
}
|
|
55
84
|
return rooms;
|
|
56
85
|
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Categorize rooms into owned vs member rooms based on is_owner flag
|
|
89
|
+
* @param rooms - Array of room info objects
|
|
90
|
+
* @returns Object with privateRoomIds (owned) and sharedRoomIds (member)
|
|
91
|
+
*/
|
|
92
|
+
private categorizeRooms(rooms: RoomInfo[]): {
|
|
93
|
+
privateRoomIds: string[];
|
|
94
|
+
sharedRoomIds: string[];
|
|
95
|
+
} {
|
|
96
|
+
const privateRoomIds: string[] = [];
|
|
97
|
+
const sharedRoomIds: string[] = [];
|
|
98
|
+
|
|
99
|
+
for (const room of rooms) {
|
|
100
|
+
if (room.is_owner) {
|
|
101
|
+
privateRoomIds.push(room.id);
|
|
102
|
+
} else {
|
|
103
|
+
sharedRoomIds.push(room.id);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return { privateRoomIds, sharedRoomIds };
|
|
108
|
+
}
|
|
57
109
|
}
|
|
@@ -22,6 +22,11 @@ export { PingHandler, PongHandler } from "./ping-pong-handler";
|
|
|
22
22
|
export { SubscribeResponseHandler } from "./subscribe-response-handler";
|
|
23
23
|
export { UnsubscribeResponseHandler } from "./unsubscribe-response-handler";
|
|
24
24
|
export { ListRoomsResponseHandler } from "./list-rooms-response-handler";
|
|
25
|
+
export { RoomOperationResponseHandler } from "./room-operation-response-handler";
|
|
26
|
+
export { AgentRoomOperationResponseHandler } from "./agent-room-operation-response-handler";
|
|
27
|
+
export { ListRoomAgentsHandler } from "./list-room-agents-handler";
|
|
28
|
+
export { ListAvailableAgentsHandler } from "./list-available-agents-handler";
|
|
29
|
+
export { AgentStatusUpdateHandler } from "./agent-status-update-handler";
|
|
25
30
|
|
|
26
31
|
// Import for convenience function
|
|
27
32
|
import { TaskResponseHandler } from "./task-response-handler";
|
|
@@ -38,6 +43,11 @@ import { PingHandler, PongHandler } from "./ping-pong-handler";
|
|
|
38
43
|
import { SubscribeResponseHandler } from "./subscribe-response-handler";
|
|
39
44
|
import { UnsubscribeResponseHandler } from "./unsubscribe-response-handler";
|
|
40
45
|
import { ListRoomsResponseHandler } from "./list-rooms-response-handler";
|
|
46
|
+
import { RoomOperationResponseHandler } from "./room-operation-response-handler";
|
|
47
|
+
import { AgentRoomOperationResponseHandler } from "./agent-room-operation-response-handler";
|
|
48
|
+
import { ListRoomAgentsHandler } from "./list-room-agents-handler";
|
|
49
|
+
import { ListAvailableAgentsHandler } from "./list-available-agents-handler";
|
|
50
|
+
import { AgentStatusUpdateHandler } from "./agent-status-update-handler";
|
|
41
51
|
import { MessageHandler } from "./types";
|
|
42
52
|
|
|
43
53
|
/**
|
|
@@ -70,6 +80,15 @@ export function getDefaultHandlers(
|
|
|
70
80
|
new UnsubscribeResponseHandler(),
|
|
71
81
|
new ListRoomsResponseHandler(),
|
|
72
82
|
|
|
83
|
+
// Room Management handlers (v2.0.0)
|
|
84
|
+
new RoomOperationResponseHandler(),
|
|
85
|
+
|
|
86
|
+
// Agent Room Management handlers (v2.0.0)
|
|
87
|
+
new AgentRoomOperationResponseHandler(),
|
|
88
|
+
new ListRoomAgentsHandler(),
|
|
89
|
+
new ListAvailableAgentsHandler(),
|
|
90
|
+
new AgentStatusUpdateHandler(),
|
|
91
|
+
|
|
73
92
|
// Keepalive handlers
|
|
74
93
|
new PingHandler(),
|
|
75
94
|
new PongHandler()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler for available_agents_response messages (v2.0.0)
|
|
3
|
+
* Processes responses from list_available_agents requests
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AvailableAgentsResponse, AvailableAgentsResponseSchema } from "../../types";
|
|
7
|
+
import { BaseMessageHandler } from "./base-handler";
|
|
8
|
+
import { HandlerContext } from "./types";
|
|
9
|
+
import { AgentRoomInfo } from "../../managers/agent-room-manager";
|
|
10
|
+
|
|
11
|
+
export class ListAvailableAgentsHandler extends BaseMessageHandler<AvailableAgentsResponse> {
|
|
12
|
+
readonly type = "available_agents_response" as const;
|
|
13
|
+
readonly schema = AvailableAgentsResponseSchema;
|
|
14
|
+
|
|
15
|
+
protected handleValidated(message: AvailableAgentsResponse, context: HandlerContext): void {
|
|
16
|
+
const { agents } = message.data;
|
|
17
|
+
|
|
18
|
+
context.logger.debug("Handling available_agents_response", {
|
|
19
|
+
agentCount: agents?.length || 0
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Parse agents array (handle undefined as empty array)
|
|
23
|
+
const agentList: AgentRoomInfo[] = agents || [];
|
|
24
|
+
|
|
25
|
+
context.logger.info("Available agents listed", {
|
|
26
|
+
count: agentList.length
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Note: We don't cache this globally since it's room-specific
|
|
30
|
+
// The AgentRoomManager will cache it with the room context
|
|
31
|
+
|
|
32
|
+
// Emit success event
|
|
33
|
+
this.emit(context, "agent_room:available_agents_listed", agentList);
|
|
34
|
+
|
|
35
|
+
// Send webhook
|
|
36
|
+
this.sendWebhook(context, "available_agents_listed", {
|
|
37
|
+
agents: agentList,
|
|
38
|
+
count: agentList.length
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler for room_agents_response messages (v2.0.0)
|
|
3
|
+
* Processes responses from list_room_agents requests
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { RoomAgentsResponse, RoomAgentsResponseSchema } from "../../types";
|
|
7
|
+
import { BaseMessageHandler } from "./base-handler";
|
|
8
|
+
import { HandlerContext } from "./types";
|
|
9
|
+
import { SDKError } from "../../types/events";
|
|
10
|
+
import { ErrorCode } from "../../types/error-codes";
|
|
11
|
+
import { AgentRoomInfo } from "../../managers/agent-room-manager";
|
|
12
|
+
|
|
13
|
+
export class ListRoomAgentsHandler extends BaseMessageHandler<RoomAgentsResponse> {
|
|
14
|
+
readonly type = "room_agents_response" as const;
|
|
15
|
+
readonly schema = RoomAgentsResponseSchema;
|
|
16
|
+
|
|
17
|
+
protected handleValidated(
|
|
18
|
+
message: RoomAgentsResponse,
|
|
19
|
+
context: HandlerContext
|
|
20
|
+
): void {
|
|
21
|
+
const { room_id, agents } = message.data;
|
|
22
|
+
|
|
23
|
+
context.logger.debug("Handling room_agents_response", {
|
|
24
|
+
roomId: room_id,
|
|
25
|
+
agentCount: agents?.length || 0
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (!room_id) {
|
|
29
|
+
const error = new SDKError(
|
|
30
|
+
"Room agents response missing room_id",
|
|
31
|
+
ErrorCode.VALIDATION_ERROR
|
|
32
|
+
);
|
|
33
|
+
this.emit(context, "agent_room:list_error", error, undefined);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Parse agents array (handle undefined as empty array)
|
|
38
|
+
const agentList: AgentRoomInfo[] = agents || [];
|
|
39
|
+
|
|
40
|
+
context.logger.info("Room agents listed", {
|
|
41
|
+
roomId: room_id,
|
|
42
|
+
count: agentList.length
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Cache via agent room manager if available
|
|
46
|
+
const agentRoomManager = (context as any).agentRoomManager;
|
|
47
|
+
if (agentRoomManager && typeof agentRoomManager.cacheRoomAgents === "function") {
|
|
48
|
+
agentRoomManager.cacheRoomAgents(room_id, agentList);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Emit success event
|
|
52
|
+
this.emit(context, "agent_room:agents_listed", room_id, agentList);
|
|
53
|
+
|
|
54
|
+
// Send webhook
|
|
55
|
+
this.sendWebhook(context, "room_agents_listed", {
|
|
56
|
+
room_id,
|
|
57
|
+
agents: agentList,
|
|
58
|
+
count: agentList.length
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|