@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.
Files changed (153) hide show
  1. package/.github/workflows/publish-npm.yml +8 -6
  2. package/CHANGELOG.md +265 -0
  3. package/README.md +406 -53
  4. package/dist/core/websocket-client.d.ts +12 -0
  5. package/dist/core/websocket-client.d.ts.map +1 -1
  6. package/dist/core/websocket-client.js +22 -2
  7. package/dist/core/websocket-client.js.map +1 -1
  8. package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts +76 -0
  9. package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts.map +1 -0
  10. package/dist/handlers/message-handlers/agent-room-operation-response-handler.js +70 -0
  11. package/dist/handlers/message-handlers/agent-room-operation-response-handler.js.map +1 -0
  12. package/dist/handlers/message-handlers/agent-selected-handler.d.ts +92 -38
  13. package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
  14. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +904 -0
  15. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -0
  16. package/dist/handlers/message-handlers/agent-status-update-handler.js +51 -0
  17. package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -0
  18. package/dist/handlers/message-handlers/auth-error-handler.d.ts +45 -31
  19. package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
  20. package/dist/handlers/message-handlers/auth-message-handler.d.ts +6 -0
  21. package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
  22. package/dist/handlers/message-handlers/auth-message-handler.js +65 -5
  23. package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
  24. package/dist/handlers/message-handlers/auth-required-handler.d.ts +49 -31
  25. package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
  26. package/dist/handlers/message-handlers/auth-success-handler.d.ts +6 -0
  27. package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
  28. package/dist/handlers/message-handlers/auth-success-handler.js +46 -4
  29. package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
  30. package/dist/handlers/message-handlers/challenge-handler.d.ts +45 -31
  31. package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
  32. package/dist/handlers/message-handlers/error-message-handler.d.ts +49 -31
  33. package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
  34. package/dist/handlers/message-handlers/index.d.ts +5 -0
  35. package/dist/handlers/message-handlers/index.d.ts.map +1 -1
  36. package/dist/handlers/message-handlers/index.js +23 -1
  37. package/dist/handlers/message-handlers/index.js.map +1 -1
  38. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +877 -0
  39. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -0
  40. package/dist/handlers/message-handlers/list-available-agents-handler.js +38 -0
  41. package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -0
  42. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +886 -0
  43. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -0
  44. package/dist/handlers/message-handlers/list-room-agents-handler.js +51 -0
  45. package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -0
  46. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +178 -89
  47. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
  48. package/dist/handlers/message-handlers/ping-pong-handler.d.ts +62 -58
  49. package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
  50. package/dist/handlers/message-handlers/regular-message-handler.d.ts +31 -29
  51. package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
  52. package/dist/handlers/message-handlers/room-operation-response-handler.d.ts +328 -0
  53. package/dist/handlers/message-handlers/room-operation-response-handler.d.ts.map +1 -0
  54. package/dist/handlers/message-handlers/room-operation-response-handler.js +92 -0
  55. package/dist/handlers/message-handlers/room-operation-response-handler.js.map +1 -0
  56. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +53 -31
  57. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
  58. package/dist/handlers/message-handlers/types.d.ts +2 -0
  59. package/dist/handlers/message-handlers/types.d.ts.map +1 -1
  60. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +53 -31
  61. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
  62. package/dist/managers/agent-room-manager.d.ts +222 -0
  63. package/dist/managers/agent-room-manager.d.ts.map +1 -0
  64. package/dist/managers/agent-room-manager.js +508 -0
  65. package/dist/managers/agent-room-manager.js.map +1 -0
  66. package/dist/managers/index.d.ts +2 -0
  67. package/dist/managers/index.d.ts.map +1 -1
  68. package/dist/managers/index.js +5 -1
  69. package/dist/managers/index.js.map +1 -1
  70. package/dist/managers/room-management-manager.d.ts +213 -0
  71. package/dist/managers/room-management-manager.d.ts.map +1 -0
  72. package/dist/managers/room-management-manager.js +440 -0
  73. package/dist/managers/room-management-manager.js.map +1 -0
  74. package/dist/managers/room-manager.d.ts +4 -4
  75. package/dist/managers/room-manager.d.ts.map +1 -1
  76. package/dist/managers/room-manager.js.map +1 -1
  77. package/dist/teneo-sdk.d.ts +333 -13
  78. package/dist/teneo-sdk.d.ts.map +1 -1
  79. package/dist/teneo-sdk.js +468 -1
  80. package/dist/teneo-sdk.js.map +1 -1
  81. package/dist/types/config.d.ts +63 -54
  82. package/dist/types/config.d.ts.map +1 -1
  83. package/dist/types/config.js +8 -4
  84. package/dist/types/config.js.map +1 -1
  85. package/dist/types/error-codes.d.ts +2 -0
  86. package/dist/types/error-codes.d.ts.map +1 -1
  87. package/dist/types/error-codes.js +3 -0
  88. package/dist/types/error-codes.js.map +1 -1
  89. package/dist/types/events.d.ts +132 -68
  90. package/dist/types/events.d.ts.map +1 -1
  91. package/dist/types/events.js.map +1 -1
  92. package/dist/types/index.d.ts +1 -1
  93. package/dist/types/index.d.ts.map +1 -1
  94. package/dist/types/index.js +27 -2
  95. package/dist/types/index.js.map +1 -1
  96. package/dist/types/messages.d.ts +11396 -2559
  97. package/dist/types/messages.d.ts.map +1 -1
  98. package/dist/types/messages.js +294 -27
  99. package/dist/types/messages.js.map +1 -1
  100. package/examples/.env.example +1 -1
  101. package/examples/agent-room-management-example.ts +334 -0
  102. package/examples/claude-agent-x-follower/.env.example +2 -2
  103. package/examples/claude-agent-x-follower/QUICKSTART.md +1 -1
  104. package/examples/claude-agent-x-follower/README.md +1 -1
  105. package/examples/n8n-teneo/.env.example +2 -2
  106. package/examples/n8n-teneo/README.md +1 -1
  107. package/examples/openai-teneo/.env.example +2 -2
  108. package/examples/openai-teneo/README.md +1 -1
  109. package/examples/production-dashboard/.env.example +2 -2
  110. package/examples/production-dashboard/README.md +89 -12
  111. package/examples/production-dashboard/public/dashboard.html +1173 -601
  112. package/examples/production-dashboard/server.ts +347 -5
  113. package/examples/room-management-example.ts +285 -0
  114. package/examples/usage/.env.example +1 -1
  115. package/examples/usage/01-connect.ts +1 -1
  116. package/examples/usage/02-list-agents.ts +1 -1
  117. package/examples/usage/03-pick-agent.ts +1 -1
  118. package/examples/usage/04-find-by-capability.ts +1 -1
  119. package/examples/usage/05-webhook-example.ts +1 -1
  120. package/examples/usage/06-simple-api-server.ts +1 -1
  121. package/examples/usage/07-event-listener.ts +1 -1
  122. package/examples/usage/README.md +1 -1
  123. package/package.json +9 -1
  124. package/src/core/websocket-client.ts +26 -2
  125. package/src/handlers/message-handlers/agent-room-operation-response-handler.ts +83 -0
  126. package/src/handlers/message-handlers/agent-status-update-handler.ts +58 -0
  127. package/src/handlers/message-handlers/auth-message-handler.ts +73 -5
  128. package/src/handlers/message-handlers/auth-success-handler.ts +58 -6
  129. package/src/handlers/message-handlers/index.ts +19 -0
  130. package/src/handlers/message-handlers/list-available-agents-handler.ts +41 -0
  131. package/src/handlers/message-handlers/list-room-agents-handler.ts +61 -0
  132. package/src/handlers/message-handlers/room-operation-response-handler.ts +105 -0
  133. package/src/handlers/message-handlers/types.ts +6 -0
  134. package/src/managers/agent-room-manager.ts +609 -0
  135. package/src/managers/index.ts +2 -0
  136. package/src/managers/room-management-manager.ts +523 -0
  137. package/src/managers/room-manager.ts +4 -5
  138. package/src/teneo-sdk.ts +505 -4
  139. package/src/types/config.ts +10 -5
  140. package/src/types/error-codes.ts +4 -0
  141. package/src/types/events.ts +24 -0
  142. package/src/types/index.ts +55 -0
  143. package/src/types/messages.ts +374 -41
  144. package/tests/integration/room-management.test.ts +514 -0
  145. package/tests/integration/websocket.test.ts +1 -1
  146. package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +394 -0
  147. package/tests/unit/handlers/agent-status-update-handler.test.ts +407 -0
  148. package/tests/unit/handlers/auth-success-handler-rooms.test.ts +699 -0
  149. package/tests/unit/handlers/list-available-agents-handler.test.ts +256 -0
  150. package/tests/unit/handlers/list-room-agents-handler.test.ts +294 -0
  151. package/tests/unit/handlers/room-operation-response-handler.test.ts +527 -0
  152. package/tests/unit/managers/agent-room-manager.test.ts +534 -0
  153. package/tests/unit/managers/room-management-manager.test.ts +438 -0
package/src/teneo-sdk.ts CHANGED
@@ -12,7 +12,6 @@ import {
12
12
  PartialSDKConfigSchema,
13
13
  SDKConfigBuilder,
14
14
  Agent,
15
- Room,
16
15
  RoomInfo,
17
16
  Logger,
18
17
  validateConfig,
@@ -32,6 +31,8 @@ import {
32
31
  import {
33
32
  ConnectionManager,
34
33
  RoomManager,
34
+ RoomManagementManager,
35
+ AgentRoomManager,
35
36
  AgentRegistry,
36
37
  MessageRouter,
37
38
  SendMessageOptions,
@@ -71,6 +72,8 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
71
72
  // Managers
72
73
  private readonly connection: ConnectionManager;
73
74
  private readonly rooms: RoomManager;
75
+ private readonly roomManagement: RoomManagementManager;
76
+ private readonly agentRoom: AgentRoomManager;
74
77
  private readonly agents: AgentRegistry;
75
78
  private readonly messages: MessageRouter;
76
79
 
@@ -149,7 +152,11 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
149
152
  // Initialize managers
150
153
  this.connection = new ConnectionManager(this.wsClient, this.logger);
151
154
  this.rooms = new RoomManager(this.wsClient, this.logger);
155
+ this.roomManagement = new RoomManagementManager(this.wsClient, this.logger);
156
+ this.agentRoom = new AgentRoomManager(this.wsClient, this.logger, this.roomManagement);
152
157
  this.wsClient.setRoomManager(this.rooms); // Enable subscription tracking in handlers
158
+ this.wsClient.setRoomManagementManager(this.roomManagement); // Enable room CRUD in handlers (v2.0.0)
159
+ this.wsClient.setAgentRoomManager(this.agentRoom); // Enable agent-room operations in handlers (v2.0.0)
153
160
  this.agents = new AgentRegistry(this.logger);
154
161
  this.messages = new MessageRouter(
155
162
  this.wsClient,
@@ -501,7 +508,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
501
508
  * });
502
509
  * ```
503
510
  */
504
- public getRooms(): ReadonlyArray<Room> {
511
+ public getRooms(): ReadonlyArray<RoomInfo> {
505
512
  return this.rooms.getRooms();
506
513
  }
507
514
 
@@ -523,10 +530,387 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
523
530
  * }
524
531
  * ```
525
532
  */
526
- public getRoom(roomId: string): Room | undefined {
533
+ public getRoom(roomId: string): RoomInfo | undefined {
527
534
  return this.rooms.getRoom(roomId);
528
535
  }
529
536
 
537
+ // ============================================================================
538
+ // ROOM MANAGEMENT API (v2.0.0)
539
+ // ============================================================================
540
+
541
+ /**
542
+ * Creates a new private or public room.
543
+ * Checks room limit before creating (for private rooms).
544
+ * Emits 'room:created' event on success, 'room:create_error' on failure.
545
+ *
546
+ * @param options - Room creation options
547
+ * @param options.name - Room name (1-100 characters)
548
+ * @param options.description - Optional room description (max 500 characters)
549
+ * @param options.isPublic - Whether room is public (default: false)
550
+ * @returns Promise that resolves with created room info
551
+ * @throws {SDKError} If not connected, over limit, or validation fails
552
+ *
553
+ * @example
554
+ * ```typescript
555
+ * const room = await sdk.createRoom({
556
+ * name: 'My Project Room',
557
+ * description: 'Collaboration space for my project',
558
+ * isPublic: false
559
+ * });
560
+ * console.log(`Created room: ${room.id}`);
561
+ * ```
562
+ */
563
+ public async createRoom(options: {
564
+ name: string;
565
+ description?: string;
566
+ isPublic?: boolean;
567
+ }): Promise<RoomInfo> {
568
+ return this.roomManagement.createRoom(options);
569
+ }
570
+
571
+ /**
572
+ * Updates an existing room's name and/or description.
573
+ * User must own the room to update it.
574
+ * Emits 'room:updated' event on success, 'room:update_error' on failure.
575
+ *
576
+ * @param roomId - ID of room to update
577
+ * @param updates - Fields to update
578
+ * @param updates.name - New room name (1-100 characters)
579
+ * @param updates.description - New room description (max 500 characters)
580
+ * @returns Promise that resolves with updated room info
581
+ * @throws {SDKError} If not connected, not owner, or validation fails
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * const room = await sdk.updateRoom('room-123', {
586
+ * name: 'Updated Room Name',
587
+ * description: 'New description'
588
+ * });
589
+ * ```
590
+ */
591
+ public async updateRoom(
592
+ roomId: string,
593
+ updates: { name?: string; description?: string }
594
+ ): Promise<RoomInfo> {
595
+ return this.roomManagement.updateRoom(roomId, updates);
596
+ }
597
+
598
+ /**
599
+ * Deletes a room permanently.
600
+ * User must own the room to delete it.
601
+ * Emits 'room:deleted' event on success, 'room:delete_error' on failure.
602
+ *
603
+ * @param roomId - ID of room to delete
604
+ * @returns Promise that resolves when room is deleted
605
+ * @throws {SDKError} If not connected or not owner
606
+ *
607
+ * @example
608
+ * ```typescript
609
+ * await sdk.deleteRoom('room-123');
610
+ * console.log('Room deleted successfully');
611
+ * ```
612
+ */
613
+ public async deleteRoom(roomId: string): Promise<void> {
614
+ return this.roomManagement.deleteRoom(roomId);
615
+ }
616
+
617
+ /**
618
+ * Gets all rooms owned by the current user.
619
+ * Synchronous method that returns cached data from authentication.
620
+ *
621
+ * @returns Array of owned room info
622
+ *
623
+ * @example
624
+ * ```typescript
625
+ * const myRooms = sdk.getOwnedRooms();
626
+ * console.log(`I own ${myRooms.length} rooms`);
627
+ * myRooms.forEach(room => {
628
+ * console.log(`- ${room.name} (${room.id})`);
629
+ * });
630
+ * ```
631
+ */
632
+ public getOwnedRooms(): ReadonlyArray<Readonly<RoomInfo>> {
633
+ return this.roomManagement.getOwnedRooms();
634
+ }
635
+
636
+ /**
637
+ * Gets all rooms the user is a member of (but doesn't own).
638
+ * Synchronous method that returns cached data from authentication.
639
+ *
640
+ * @returns Array of shared room info
641
+ *
642
+ * @example
643
+ * ```typescript
644
+ * const sharedRooms = sdk.getSharedRooms();
645
+ * console.log(`I'm a member of ${sharedRooms.length} shared rooms`);
646
+ * ```
647
+ */
648
+ public getSharedRooms(): ReadonlyArray<Readonly<RoomInfo>> {
649
+ return this.roomManagement.getSharedRooms();
650
+ }
651
+
652
+ /**
653
+ * Gets all rooms the user has access to (both owned and shared).
654
+ * Convenience method that combines getOwnedRooms() and getSharedRooms().
655
+ * Synchronous method that returns cached data from authentication.
656
+ *
657
+ * @returns Array of all room info (owned + shared)
658
+ *
659
+ * @example
660
+ * ```typescript
661
+ * const allRooms = sdk.getAllRooms();
662
+ * console.log(`I have access to ${allRooms.length} total rooms`);
663
+ *
664
+ * // You can filter by ownership if needed
665
+ * const myRooms = allRooms.filter(r => r.is_owner);
666
+ * const sharedWithMe = allRooms.filter(r => !r.is_owner);
667
+ * ```
668
+ */
669
+ public getAllRooms(): ReadonlyArray<Readonly<RoomInfo>> {
670
+ return this.roomManagement.getAllRooms();
671
+ }
672
+
673
+ /**
674
+ * Gets the maximum number of private rooms the user can create.
675
+ * Based on user's subscription/plan.
676
+ *
677
+ * @returns Maximum private room limit
678
+ *
679
+ * @example
680
+ * ```typescript
681
+ * const limit = sdk.getRoomLimit();
682
+ * const current = sdk.getOwnedRoomCount();
683
+ * console.log(`Using ${current}/${limit} room slots`);
684
+ * ```
685
+ */
686
+ public getRoomLimit(): number {
687
+ return this.roomManagement.getRoomLimit();
688
+ }
689
+
690
+ /**
691
+ * Gets the current count of owned private rooms.
692
+ *
693
+ * @returns Number of rooms user owns
694
+ *
695
+ * @example
696
+ * ```typescript
697
+ * const count = sdk.getOwnedRoomCount();
698
+ * if (sdk.canCreateRoom()) {
699
+ * console.log(`Can create ${sdk.getRoomLimit() - count} more rooms`);
700
+ * }
701
+ * ```
702
+ */
703
+ public getOwnedRoomCount(): number {
704
+ return this.roomManagement.getOwnedRoomCount();
705
+ }
706
+
707
+ /**
708
+ * Checks if user can create another private room.
709
+ * Compares current owned room count against limit.
710
+ *
711
+ * @returns True if under limit, false otherwise
712
+ *
713
+ * @example
714
+ * ```typescript
715
+ * if (sdk.canCreateRoom()) {
716
+ * await sdk.createRoom({ name: 'New Room' });
717
+ * } else {
718
+ * console.log('Room limit reached! Upgrade your plan.');
719
+ * }
720
+ * ```
721
+ */
722
+ public canCreateRoom(): boolean {
723
+ return this.roomManagement.canCreateRoom();
724
+ }
725
+
726
+ // ============================================================================
727
+ // AGENT ROOM MANAGEMENT API (v2.0.0)
728
+ // ============================================================================
729
+
730
+ /**
731
+ * Adds an agent to a room. Only room owners can add agents.
732
+ * Emits 'agent_room:agent_added' on success, 'agent_room:add_error' on failure.
733
+ *
734
+ * @param roomId - ID of the room to add the agent to
735
+ * @param agentId - ID of the agent to add
736
+ * @returns Promise that resolves when agent is added
737
+ * @throws {SDKError} If not connected, not owner, or agent already in room
738
+ *
739
+ * @example
740
+ * ```typescript
741
+ * await sdk.addAgentToRoom('room-123', 'weather-agent');
742
+ * console.log('Agent added to room');
743
+ * ```
744
+ */
745
+ public async addAgentToRoom(roomId: string, agentId: string): Promise<void> {
746
+ return this.agentRoom.addAgentToRoom(roomId, agentId);
747
+ }
748
+
749
+ /**
750
+ * Removes an agent from a room. Only room owners can remove agents.
751
+ * Emits 'agent_room:agent_removed' on success, 'agent_room:remove_error' on failure.
752
+ *
753
+ * @param roomId - ID of the room to remove the agent from
754
+ * @param agentId - ID of the agent to remove
755
+ * @returns Promise that resolves when agent is removed
756
+ * @throws {SDKError} If not connected, not owner, or agent not in room
757
+ *
758
+ * @example
759
+ * ```typescript
760
+ * await sdk.removeAgentFromRoom('room-123', 'weather-agent');
761
+ * console.log('Agent removed from room');
762
+ * ```
763
+ */
764
+ public async removeAgentFromRoom(roomId: string, agentId: string): Promise<void> {
765
+ return this.agentRoom.removeAgentFromRoom(roomId, agentId);
766
+ }
767
+
768
+ /**
769
+ * Lists all agents in a room.
770
+ * Results are cached for 5 minutes for performance.
771
+ * Emits 'agent_room:agents_listed' when list is received.
772
+ *
773
+ * @param roomId - ID of the room to list agents for
774
+ * @param useCache - Whether to use cached data if available (default: true)
775
+ * @returns Promise that resolves to array of agents in the room
776
+ * @throws {SDKError} If not connected
777
+ *
778
+ * @example
779
+ * ```typescript
780
+ * const agents = await sdk.listRoomAgents('room-123');
781
+ * console.log(`Room has ${agents.length} agents`);
782
+ * agents.forEach(agent => {
783
+ * console.log(`- ${agent.agent_name} (${agent.status})`);
784
+ * });
785
+ * ```
786
+ */
787
+ public async listRoomAgents(roomId: string, useCache: boolean = true): Promise<any[]> {
788
+ return this.agentRoom.listRoomAgents(roomId, useCache);
789
+ }
790
+
791
+ /**
792
+ * Lists all agents available to be added to a room.
793
+ * Shows agents not currently in the room.
794
+ * Results are cached for 5 minutes for performance.
795
+ * Emits 'agent_room:available_agents_listed' when list is received.
796
+ *
797
+ * @param roomId - ID of the room to check available agents for
798
+ * @param useCache - Whether to use cached data if available (default: true)
799
+ * @returns Promise that resolves to array of available agents
800
+ * @throws {SDKError} If not connected
801
+ *
802
+ * @example
803
+ * ```typescript
804
+ * const available = await sdk.listAvailableAgents('room-123');
805
+ * console.log(`${available.length} agents available to add`);
806
+ * ```
807
+ */
808
+ public async listAvailableAgents(roomId: string, useCache: boolean = true): Promise<any[]> {
809
+ return this.agentRoom.listAvailableAgents(roomId, useCache);
810
+ }
811
+
812
+ /**
813
+ * Gets agents in a room from cache (synchronous).
814
+ * Returns undefined if not cached. Use listRoomAgents() to fetch.
815
+ *
816
+ * @param roomId - ID of the room
817
+ * @returns Array of agents if cached, undefined otherwise
818
+ *
819
+ * @example
820
+ * ```typescript
821
+ * const agents = sdk.getRoomAgents('room-123');
822
+ * if (agents) {
823
+ * console.log(`${agents.length} agents (cached)`);
824
+ * } else {
825
+ * await sdk.listRoomAgents('room-123'); // Fetch from server
826
+ * }
827
+ * ```
828
+ */
829
+ public getRoomAgents(roomId: string): any[] | undefined {
830
+ return this.agentRoom.getRoomAgents(roomId);
831
+ }
832
+
833
+ /**
834
+ * Gets available agents for a room from cache (synchronous).
835
+ * Returns undefined if not cached. Use listAvailableAgents() to fetch.
836
+ *
837
+ * @param roomId - ID of the room
838
+ * @returns Array of available agents if cached, undefined otherwise
839
+ *
840
+ * @example
841
+ * ```typescript
842
+ * const available = sdk.getAvailableAgents('room-123');
843
+ * if (available) {
844
+ * console.log(`${available.length} agents available (cached)`);
845
+ * }
846
+ * ```
847
+ */
848
+ public getAvailableAgents(roomId: string): any[] | undefined {
849
+ return this.agentRoom.getAvailableAgents(roomId);
850
+ }
851
+
852
+ /**
853
+ * Checks if an agent is in a room (synchronous, from cache).
854
+ * Returns undefined if room data not cached.
855
+ *
856
+ * @param roomId - ID of the room
857
+ * @param agentId - ID of the agent
858
+ * @returns True if agent is in room, false if not, undefined if not cached
859
+ *
860
+ * @example
861
+ * ```typescript
862
+ * const inRoom = sdk.isAgentInRoom('room-123', 'weather-agent');
863
+ * if (inRoom === true) {
864
+ * console.log('Agent is in room');
865
+ * } else if (inRoom === false) {
866
+ * console.log('Agent is not in room');
867
+ * } else {
868
+ * console.log('Room data not cached');
869
+ * }
870
+ * ```
871
+ */
872
+ public isAgentInRoom(roomId: string, agentId: string): boolean | undefined {
873
+ return this.agentRoom.isAgentInRoom(roomId, agentId);
874
+ }
875
+
876
+ /**
877
+ * Gets the count of agents in a room (synchronous, from cache).
878
+ * Returns undefined if room data not cached.
879
+ *
880
+ * @param roomId - ID of the room
881
+ * @returns Number of agents in room, or undefined if not cached
882
+ *
883
+ * @example
884
+ * ```typescript
885
+ * const count = sdk.getRoomAgentCount('room-123');
886
+ * if (count !== undefined) {
887
+ * console.log(`Room has ${count} agents`);
888
+ * }
889
+ * ```
890
+ */
891
+ public getRoomAgentCount(roomId: string): number | undefined {
892
+ return this.agentRoom.getRoomAgentCount(roomId);
893
+ }
894
+
895
+ /**
896
+ * Invalidates the agent-room cache for a specific room.
897
+ * Forces the next listRoomAgents() or listAvailableAgents() call to fetch fresh data.
898
+ * Useful after bulk operations or when you know the cache is stale.
899
+ *
900
+ * @param roomId - ID of the room to invalidate cache for
901
+ *
902
+ * @example
903
+ * ```typescript
904
+ * // After adding/removing agents
905
+ * await sdk.addAgentToRoom('room-123', 'agent-456');
906
+ * sdk.invalidateAgentRoomCache('room-123');
907
+ * const freshAgents = await sdk.listRoomAgents('room-123');
908
+ * ```
909
+ */
910
+ public invalidateAgentRoomCache(roomId: string): void {
911
+ this.agentRoom.invalidateCache(roomId);
912
+ }
913
+
530
914
  /**
531
915
  * Configures webhook URL and headers for receiving real-time event notifications.
532
916
  * Webhooks allow you to receive events at your server endpoint via HTTP POST requests.
@@ -951,7 +1335,9 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
951
1335
  this.connection.on("auth:success", (state) => {
952
1336
  this.logger.debug("Received auth:success event in SDK", {
953
1337
  authenticated: state?.authenticated,
954
- hasRooms: !!state?.roomObjects
1338
+ hasRooms: !!state?.roomObjects,
1339
+ ownedRooms: state?.privateRoomIds?.length || 0,
1340
+ sharedRooms: state?.sharedRoomIds?.length || 0
955
1341
  });
956
1342
 
957
1343
  // Update rooms from auth state
@@ -959,6 +1345,19 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
959
1345
  this.rooms.updateRoomsFromAuth(state.roomObjects);
960
1346
  }
961
1347
 
1348
+ // Ensure RoomManagementManager is synced with auth state
1349
+ // This handles cases where auth handlers might have already set it, but ensures consistency
1350
+ if (state.roomObjects && state.roomObjects.length > 0) {
1351
+ const ownedRooms = state.roomObjects.filter((r) => r.is_owner);
1352
+ const sharedRooms = state.roomObjects.filter((r) => !r.is_owner);
1353
+ this.roomManagement.setOwnedRooms(ownedRooms);
1354
+ this.roomManagement.setSharedRooms(sharedRooms);
1355
+
1356
+ if (state.maxPrivateRooms) {
1357
+ this.roomManagement.setRoomLimit(state.maxPrivateRooms);
1358
+ }
1359
+ }
1360
+
962
1361
  this.emit("auth:success", state);
963
1362
  });
964
1363
  this.connection.on("auth:error", (error) => this.emit("auth:error", error));
@@ -993,6 +1392,108 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
993
1392
  this.wsClient.on("room:subscribed", (data) => this.emit("room:subscribed", data));
994
1393
  this.wsClient.on("room:unsubscribed", (data) => this.emit("room:unsubscribed", data));
995
1394
 
1395
+ // Forward room management events from WebSocketClient (emitted by handlers) (v2.0.0)
1396
+ // These events are emitted by message handlers, so we listen on wsClient
1397
+ // We forward to RoomManagementManager first (for promise resolution), then emit on SDK
1398
+ this.wsClient.on("room:created", (room) => {
1399
+ // Update RoomManagementManager cache
1400
+ this.roomManagement.upsertRoom(room);
1401
+ // Emit on RoomManagementManager for promise resolution (see createRoom method)
1402
+ this.roomManagement.emit("room:created", room);
1403
+ // Emit on SDK for external listeners
1404
+ this.emit("room:created", room);
1405
+ });
1406
+ this.wsClient.on("room:updated", (room) => {
1407
+ // Update RoomManagementManager cache
1408
+ this.roomManagement.upsertRoom(room);
1409
+ // Emit on RoomManagementManager for promise resolution (see updateRoom method)
1410
+ this.roomManagement.emit("room:updated", room);
1411
+ // Emit on SDK for external listeners
1412
+ this.emit("room:updated", room);
1413
+ });
1414
+ this.wsClient.on("room:deleted", (roomId) => {
1415
+ // Remove from RoomManagementManager cache
1416
+ this.roomManagement.removeRoom(roomId);
1417
+ // Emit on RoomManagementManager for promise resolution (see deleteRoom method)
1418
+ this.roomManagement.emit("room:deleted", roomId);
1419
+ // Emit on SDK for external listeners
1420
+ this.emit("room:deleted", roomId);
1421
+ });
1422
+ this.wsClient.on("room:create_error", (error) => {
1423
+ // Emit on RoomManagementManager for promise rejection
1424
+ this.roomManagement.emit("room:create_error", error);
1425
+ // Emit on SDK for external listeners
1426
+ this.emit("room:create_error", error);
1427
+ });
1428
+ this.wsClient.on("room:update_error", (error, roomId) => {
1429
+ // Emit on RoomManagementManager for promise rejection
1430
+ this.roomManagement.emit("room:update_error", error, roomId);
1431
+ // Emit on SDK for external listeners
1432
+ this.emit("room:update_error", error, roomId);
1433
+ });
1434
+ this.wsClient.on("room:delete_error", (error, roomId) => {
1435
+ // Emit on RoomManagementManager for promise rejection
1436
+ this.roomManagement.emit("room:delete_error", error, roomId);
1437
+ // Emit on SDK for external listeners
1438
+ this.emit("room:delete_error", error, roomId);
1439
+ });
1440
+
1441
+ // Forward agent room management events from WebSocketClient (emitted by handlers) (v2.0.0)
1442
+ // These events are emitted by message handlers, so we listen on wsClient
1443
+ // We forward to AgentRoomManager first (for promise resolution), then emit on SDK
1444
+ this.wsClient.on("agent_room:agent_added", (roomId, agentId) => {
1445
+ // Emit on AgentRoomManager for promise resolution (see addAgentToRoom method)
1446
+ this.agentRoom.emit("agent_room:agent_added", roomId, agentId);
1447
+ // Emit on SDK for external listeners
1448
+ this.emit("agent_room:agent_added", roomId, agentId);
1449
+ });
1450
+ this.wsClient.on("agent_room:agent_removed", (roomId, agentId) => {
1451
+ // Emit on AgentRoomManager for promise resolution (see removeAgentFromRoom method)
1452
+ this.agentRoom.emit("agent_room:agent_removed", roomId, agentId);
1453
+ // Emit on SDK for external listeners
1454
+ this.emit("agent_room:agent_removed", roomId, agentId);
1455
+ });
1456
+ this.wsClient.on("agent_room:agents_listed", (roomId, agents) => {
1457
+ // Emit on AgentRoomManager for promise resolution
1458
+ this.agentRoom.emit("agent_room:agents_listed", roomId, agents);
1459
+ // Emit on SDK for external listeners
1460
+ this.emit("agent_room:agents_listed", roomId, agents);
1461
+ });
1462
+ this.wsClient.on("agent_room:available_agents_listed", (agents) => {
1463
+ // Emit on AgentRoomManager for promise resolution
1464
+ this.agentRoom.emit("agent_room:available_agents_listed", agents);
1465
+ // Emit on SDK for external listeners
1466
+ this.emit("agent_room:available_agents_listed", agents);
1467
+ });
1468
+ this.wsClient.on("agent_room:status_update", (data) => {
1469
+ // Emit on SDK for external listeners
1470
+ this.emit("agent_room:status_update", data);
1471
+ });
1472
+ this.wsClient.on("agent_room:add_error", (error, roomId) => {
1473
+ // Emit on AgentRoomManager for promise rejection
1474
+ this.agentRoom.emit("agent_room:add_error", error, roomId);
1475
+ // Emit on SDK for external listeners
1476
+ this.emit("agent_room:add_error", error, roomId);
1477
+ });
1478
+ this.wsClient.on("agent_room:remove_error", (error, roomId) => {
1479
+ // Emit on AgentRoomManager for promise rejection
1480
+ this.agentRoom.emit("agent_room:remove_error", error, roomId);
1481
+ // Emit on SDK for external listeners
1482
+ this.emit("agent_room:remove_error", error, roomId);
1483
+ });
1484
+ this.wsClient.on("agent_room:list_error", (error, roomId) => {
1485
+ // Emit on AgentRoomManager for promise rejection
1486
+ this.agentRoom.emit("agent_room:list_error", error, roomId);
1487
+ // Emit on SDK for external listeners
1488
+ this.emit("agent_room:list_error", error, roomId);
1489
+ });
1490
+ this.wsClient.on("agent_room:list_available_error", (error) => {
1491
+ // Emit on AgentRoomManager for promise rejection
1492
+ this.agentRoom.emit("agent_room:list_available_error", error);
1493
+ // Emit on SDK for external listeners
1494
+ this.emit("agent_room:list_available_error", error);
1495
+ });
1496
+
996
1497
  // Forward webhook events from WebhookHandler
997
1498
  this.webhookHandler.on("webhook:sent", (payload, url) =>
998
1499
  this.emit("webhook:sent", payload, url)
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { z } from "zod";
7
- import { ClientTypeSchema, RoomSchema, MessageTypeSchema, MessageType } from "./messages";
7
+ import { ClientTypeSchema, RoomInfoSchema, MessageTypeSchema, MessageType } from "./messages";
8
8
  import { RetryStrategySchema, type RetryStrategy } from "../utils/retry-policy";
9
9
  import type { SecurePrivateKey } from "../utils/secure-private-key";
10
10
 
@@ -146,11 +146,16 @@ export const AuthenticationStateSchema = z.object({
146
146
  isWhitelisted: z.boolean().optional(),
147
147
  isAdmin: z.boolean().optional(),
148
148
  nftVerified: z.boolean().optional(),
149
- rooms: z.array(z.string()).optional(), // Room IDs for backward compatibility
150
- roomObjects: z.array(RoomSchema).optional(), // Full room objects from auth
151
- privateRoomId: z.string().optional(),
149
+ rooms: z.array(z.string()).optional(), // Room IDs for backward compatibility (deprecated)
150
+ roomObjects: z.array(RoomInfoSchema).optional(), // Full room objects from auth (v2.0.0: uses RoomInfo)
151
+ privateRoomId: z.string().optional(), // DEPRECATED: Single room ID (use privateRoomIds instead)
152
152
  challenge: z.string().optional(),
153
- challengeTimestamp: z.number().optional()
153
+ challengeTimestamp: z.number().optional(),
154
+
155
+ // NEW in v2.0.0: Room categorization
156
+ privateRoomIds: z.array(z.string()).optional(), // IDs of rooms user owns
157
+ sharedRoomIds: z.array(z.string()).optional(), // IDs of rooms user is member of
158
+ maxPrivateRooms: z.number().optional() // Max rooms user can create
154
159
  });
155
160
 
156
161
  // Webhook config schema
@@ -38,6 +38,10 @@ export enum ErrorCode {
38
38
  // Rate limit
39
39
  RATE_LIMIT = "RATE_LIMIT",
40
40
 
41
+ // Room Management errors (v2.0.0)
42
+ OPERATION_FAILED = "OPERATION_FAILED",
43
+ PERMISSION_DENIED = "PERMISSION_DENIED",
44
+
41
45
  // Generic timeout (for backward compatibility)
42
46
  TIMEOUT_ERROR = "TIMEOUT_ERROR",
43
47
  TIMEOUT = "TIMEOUT"
@@ -303,6 +303,30 @@ export interface SDKEvents {
303
303
  "room:message": (roomId: string, message: z.infer<typeof BaseMessageSchema>) => void;
304
304
  "room:list": (rooms: z.infer<typeof RoomInfoSchema>[]) => void;
305
305
 
306
+ // Room Management events (v2.0.0)
307
+ "room:created": (room: z.infer<typeof RoomInfoSchema>) => void;
308
+ "room:updated": (room: z.infer<typeof RoomInfoSchema>) => void;
309
+ "room:deleted": (roomId: string) => void;
310
+ "room:create_error": (error: Error) => void;
311
+ "room:update_error": (error: Error, roomId?: string) => void;
312
+ "room:delete_error": (error: Error, roomId?: string) => void;
313
+
314
+ // Agent Room Management events (v2.0.0)
315
+ "agent_room:agent_added": (roomId: string, agentId: string) => void;
316
+ "agent_room:agent_removed": (roomId: string, agentId: string) => void;
317
+ "agent_room:agents_listed": (roomId: string, agents: any[]) => void;
318
+ "agent_room:available_agents_listed": (agents: any[]) => void;
319
+ "agent_room:status_update": (data: {
320
+ roomId: string;
321
+ agentId: string;
322
+ status: string;
323
+ agent?: any;
324
+ }) => void;
325
+ "agent_room:add_error": (error: Error, roomId?: string) => void;
326
+ "agent_room:remove_error": (error: Error, roomId?: string) => void;
327
+ "agent_room:list_error": (error: Error, roomId?: string) => void;
328
+ "agent_room:list_available_error": (error: Error) => void;
329
+
306
330
  // Coordinator events
307
331
  "coordinator:processing": (userRequest: string) => void;
308
332
  "coordinator:selected": (agentId: string, reasoning: string) => void;