@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
@@ -0,0 +1,334 @@
1
+ /**
2
+ * Agent Room Management Example
3
+ *
4
+ * Demonstrates how to customize which agents are available in each room using Teneo SDK v2.0.
5
+ *
6
+ * This example shows:
7
+ * - Listing available agents for a room
8
+ * - Adding specific agents to your room
9
+ * - Listing agents currently in a room
10
+ * - Removing agents from a room
11
+ * - Using cache for performance
12
+ * - Real-time agent status updates
13
+ *
14
+ * Prerequisites:
15
+ * - Set TENEO_WS_URL environment variable
16
+ * - Set PRIVATE_KEY environment variable (64 hex characters, no 0x prefix)
17
+ * - Have at least one owned room
18
+ *
19
+ * Run:
20
+ * npx ts-node examples/agent-room-management-example.ts
21
+ */
22
+
23
+ import { TeneoSDK } from "../src";
24
+ import * as dotenv from "dotenv";
25
+
26
+ dotenv.config();
27
+
28
+ const wsUrl = process.env.TENEO_WS_URL!;
29
+ const privateKey = process.env.PRIVATE_KEY!;
30
+
31
+ async function main() {
32
+ console.log("🚀 Teneo SDK v2.0 - Agent Room Management Example\n");
33
+
34
+ // Initialize SDK
35
+ const sdk = new TeneoSDK({
36
+ wsUrl,
37
+ privateKey,
38
+ logLevel: "info",
39
+ reconnect: true
40
+ });
41
+
42
+ // Set up event listeners
43
+ setupEventListeners(sdk);
44
+
45
+ try {
46
+ // Connect and authenticate
47
+ console.log("📡 Connecting to Teneo network...");
48
+ await sdk.connect();
49
+ console.log("✅ Connected and authenticated\n");
50
+
51
+ // Wait for initial data to load
52
+ await new Promise(resolve => setTimeout(resolve, 1000));
53
+
54
+ // Step 1: Get or create a test room
55
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
56
+ console.log("🏠 Setting Up Test Room");
57
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
58
+ const testRoom = await getOrCreateTestRoom(sdk);
59
+
60
+ if (!testRoom) {
61
+ console.log("❌ Could not get or create a test room");
62
+ return;
63
+ }
64
+
65
+ console.log(`Using room: "${testRoom.name}" (${testRoom.id})\n`);
66
+
67
+ // Step 2: List current agents in the room
68
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
69
+ console.log("📋 Current Agents in Room");
70
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
71
+ const currentAgents = await sdk.listRoomAgents(testRoom.id, false); // Force fresh data
72
+ displayAgents(currentAgents, "room");
73
+
74
+ // Step 3: List available agents (not yet in room)
75
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
76
+ console.log("🆕 Available Agents (Not in Room)");
77
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
78
+ const availableAgents = await sdk.listAvailableAgents(testRoom.id, false);
79
+ displayAgents(availableAgents, "available");
80
+
81
+ // Step 4: Add agents to the room
82
+ if (availableAgents.length > 0) {
83
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
84
+ console.log("➕ Adding Agents to Room");
85
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
86
+ await addAgentsToRoom(sdk, testRoom.id, availableAgents);
87
+
88
+ // Wait for additions to process
89
+ await new Promise(resolve => setTimeout(resolve, 500));
90
+ }
91
+
92
+ // Step 5: List updated room agents (using cache this time)
93
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
94
+ console.log("📋 Updated Room Agents (from cache)");
95
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
96
+ const updatedAgents = await sdk.listRoomAgents(testRoom.id, true); // Use cache
97
+ displayAgents(updatedAgents, "room");
98
+
99
+ // Step 6: Demonstrate synchronous query methods
100
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
101
+ console.log("⚡ Instant Cache Queries (No Network Call)");
102
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
103
+ demonstrateCacheQueries(sdk, testRoom.id, updatedAgents);
104
+
105
+ // Step 7: Remove agents from the room
106
+ if (updatedAgents.length > 0) {
107
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
108
+ console.log("➖ Removing Agents from Room");
109
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
110
+ await removeAgentsFromRoom(sdk, testRoom.id, updatedAgents);
111
+
112
+ // Wait for removals to process
113
+ await new Promise(resolve => setTimeout(resolve, 500));
114
+ }
115
+
116
+ // Step 8: Final room status
117
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
118
+ console.log("📊 Final Room Status");
119
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
120
+ const finalAgents = await sdk.listRoomAgents(testRoom.id, false);
121
+ displayAgents(finalAgents, "room");
122
+
123
+ // Step 9: Demonstrate cache invalidation
124
+ console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
125
+ console.log("🔄 Cache Management");
126
+ console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
127
+ console.log("Cache is automatically invalidated when:");
128
+ console.log(" ✓ You add an agent to the room");
129
+ console.log(" ✓ You remove an agent from the room");
130
+ console.log(" ✓ An agent's status changes");
131
+ console.log(" ✓ Cache TTL expires (5 minutes)");
132
+ console.log("\nManual cache invalidation:");
133
+ sdk.invalidateAgentRoomCache(testRoom.id);
134
+ console.log(` ✅ Cache cleared for room ${testRoom.id}`);
135
+
136
+ console.log("\n✅ Agent room management example completed!");
137
+
138
+ } catch (error: any) {
139
+ console.error("\n❌ Error:", error.message);
140
+ console.error(error.stack);
141
+ } finally {
142
+ // Disconnect
143
+ console.log("\n👋 Disconnecting...");
144
+ sdk.disconnect();
145
+ console.log("✅ Disconnected");
146
+ }
147
+ }
148
+
149
+ function setupEventListeners(sdk: TeneoSDK) {
150
+ // Agent added
151
+ sdk.on("agent_room:agent_added", (roomId, agentId) => {
152
+ console.log(` ✅ Agent ${agentId} added to room ${roomId}`);
153
+ });
154
+
155
+ // Agent removed
156
+ sdk.on("agent_room:agent_removed", (roomId, agentId) => {
157
+ console.log(` ✅ Agent ${agentId} removed from room ${roomId}`);
158
+ });
159
+
160
+ // Agents listed
161
+ sdk.on("agent_room:agents_listed", (roomId, agents) => {
162
+ console.log(` 📋 Listed ${agents.length} agents in room ${roomId}`);
163
+ });
164
+
165
+ // Available agents listed
166
+ sdk.on("agent_room:available_agents_listed", (agents) => {
167
+ console.log(` 📋 Listed ${agents.length} available agents`);
168
+ });
169
+
170
+ // Status updates (real-time)
171
+ sdk.on("agent_room:status_update", (data) => {
172
+ console.log(` 🔄 Agent ${data.agentId} status updated in room ${data.roomId}`);
173
+ console.log(` New status: ${data.status}`);
174
+ });
175
+
176
+ // Error events
177
+ sdk.on("agent_room:add_error", (error, roomId) => {
178
+ console.error(` ❌ Failed to add agent to room ${roomId}: ${error.message}`);
179
+ });
180
+
181
+ sdk.on("agent_room:remove_error", (error, roomId) => {
182
+ console.error(` ❌ Failed to remove agent from room ${roomId}: ${error.message}`);
183
+ });
184
+
185
+ sdk.on("agent_room:list_error", (error, roomId) => {
186
+ console.error(` ❌ Failed to list agents in room ${roomId}: ${error.message}`);
187
+ });
188
+ }
189
+
190
+ async function getOrCreateTestRoom(sdk: TeneoSDK) {
191
+ // Try to get an existing owned room
192
+ const ownedRooms = sdk.getOwnedRooms();
193
+
194
+ if (ownedRooms.length > 0) {
195
+ console.log(`Found ${ownedRooms.length} existing owned room(s)`);
196
+ console.log(`Using first room: "${ownedRooms[0].name}"`);
197
+ return ownedRooms[0];
198
+ }
199
+
200
+ // Create a new test room
201
+ console.log("No owned rooms found. Creating test room...");
202
+
203
+ if (!sdk.canCreateRoom()) {
204
+ console.log("⚠️ Cannot create room - limit reached");
205
+ console.log(` Current: ${sdk.getOwnedRoomCount()}/${sdk.getRoomLimit()}`);
206
+ return null;
207
+ }
208
+
209
+ try {
210
+ const room = await sdk.createRoom({
211
+ name: "Agent Test Room",
212
+ description: "Room for testing agent customization (SDK v2.0 example)"
213
+ });
214
+ console.log(`✅ Created test room: ${room.id}`);
215
+ return room;
216
+ } catch (error: any) {
217
+ console.error(`Failed to create test room: ${error.message}`);
218
+ return null;
219
+ }
220
+ }
221
+
222
+ function displayAgents(agents: any[], type: "room" | "available") {
223
+ if (agents.length === 0) {
224
+ console.log(` (No ${type === "room" ? "agents in room" : "available agents"})`);
225
+ return;
226
+ }
227
+
228
+ console.log(`Found ${agents.length} agent(s):\n`);
229
+
230
+ agents.forEach((agent, i) => {
231
+ console.log(`${i + 1}. ${agent.agent_name || "Unnamed Agent"}`);
232
+ console.log(` ID: ${agent.agent_id}`);
233
+
234
+ if (agent.description) {
235
+ console.log(` Description: ${agent.description}`);
236
+ }
237
+
238
+ if (agent.status) {
239
+ console.log(` Status: ${agent.status}`);
240
+ }
241
+
242
+ if (agent.capabilities && agent.capabilities.length > 0) {
243
+ const capNames = agent.capabilities.map((c: any) => c.name).join(", ");
244
+ console.log(` Capabilities: ${capNames}`);
245
+ }
246
+
247
+ if (agent.commands && agent.commands.length > 0) {
248
+ const cmdTriggers = agent.commands.map((c: any) => `/${c.trigger}`).join(", ");
249
+ console.log(` Commands: ${cmdTriggers}`);
250
+ }
251
+
252
+ if (agent.image) {
253
+ console.log(` Image: ${agent.image.substring(0, 50)}...`);
254
+ }
255
+
256
+ if (agent.added_at) {
257
+ console.log(` Added at: ${agent.added_at}`);
258
+ }
259
+
260
+ if (agent.added_by) {
261
+ console.log(` Added by: ${agent.added_by}`);
262
+ }
263
+
264
+ console.log();
265
+ });
266
+ }
267
+
268
+ async function addAgentsToRoom(sdk: TeneoSDK, roomId: string, availableAgents: any[]) {
269
+ // Add up to 2 agents from the available list
270
+ const agentsToAdd = availableAgents.slice(0, 2);
271
+
272
+ console.log(`Adding ${agentsToAdd.length} agent(s) to the room...\n`);
273
+
274
+ for (const agent of agentsToAdd) {
275
+ try {
276
+ console.log(`Adding "${agent.agent_name}" (${agent.agent_id})...`);
277
+ await sdk.addAgentToRoom(roomId, agent.agent_id);
278
+ // Wait a bit between additions
279
+ await new Promise(resolve => setTimeout(resolve, 300));
280
+ } catch (error: any) {
281
+ console.error(`Failed to add agent ${agent.agent_id}: ${error.message}`);
282
+ }
283
+ }
284
+ }
285
+
286
+ async function removeAgentsFromRoom(sdk: TeneoSDK, roomId: string, roomAgents: any[]) {
287
+ // Remove up to 2 agents
288
+ const agentsToRemove = roomAgents.slice(0, 2);
289
+
290
+ console.log(`Removing ${agentsToRemove.length} agent(s) from the room...\n`);
291
+
292
+ for (const agent of agentsToRemove) {
293
+ try {
294
+ console.log(`Removing "${agent.agent_name}" (${agent.agent_id})...`);
295
+ await sdk.removeAgentFromRoom(roomId, agent.agent_id);
296
+ // Wait a bit between removals
297
+ await new Promise(resolve => setTimeout(resolve, 300));
298
+ } catch (error: any) {
299
+ console.error(`Failed to remove agent ${agent.agent_id}: ${error.message}`);
300
+ }
301
+ }
302
+ }
303
+
304
+ function demonstrateCacheQueries(sdk: TeneoSDK, roomId: string, agents: any[]) {
305
+ // Get agent count (instant, from cache)
306
+ const count = sdk.getRoomAgentCount(roomId);
307
+ console.log(`Room agent count: ${count}`);
308
+
309
+ // Get cached agents (instant)
310
+ const cachedAgents = sdk.getRoomAgents(roomId);
311
+ if (cachedAgents) {
312
+ const names = cachedAgents.map(a => a.agent_name || "Unnamed").join(", ");
313
+ console.log(`Cached agents: ${names}`);
314
+ }
315
+
316
+ // Check if specific agent is in room (instant)
317
+ if (agents.length > 0) {
318
+ const firstAgent = agents[0];
319
+ const isInRoom = sdk.isAgentInRoom(roomId, firstAgent.agent_id);
320
+ console.log(`Is "${firstAgent.agent_name}" in room? ${isInRoom === true ? "✅ Yes" : isInRoom === false ? "❌ No" : "❓ Unknown (no cache)"}`);
321
+ }
322
+
323
+ // Get cached available agents (instant)
324
+ const cachedAvailable = sdk.getAvailableAgents(roomId);
325
+ if (cachedAvailable) {
326
+ console.log(`Cached available agents: ${cachedAvailable.length}`);
327
+ }
328
+
329
+ console.log("\n💡 These queries are instant - no network calls!");
330
+ console.log(" Cache is automatically maintained and invalidated as needed.");
331
+ }
332
+
333
+ // Run the example
334
+ main().catch(console.error);
@@ -7,8 +7,8 @@
7
7
 
8
8
  # WebSocket URL for Teneo AI Network
9
9
  # Production: wss://your-production-server.com/ws
10
- # Development: wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
11
- WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
10
+ # Development: wss://your-teneo-server.com/ws
11
+ WS_URL=wss://your-teneo-server.com/ws
12
12
 
13
13
  # Ethereum Private Key (with 0x prefix)
14
14
  # IMPORTANT: Never commit your actual private key to version control!
@@ -27,7 +27,7 @@ Edit `.env` with your credentials:
27
27
 
28
28
  ```env
29
29
  # Required: Teneo Network Connection
30
- WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
30
+ WS_URL=wss://your-teneo-server.com/ws
31
31
  PRIVATE_KEY=0x1234567890123456789012345678901234567890123456789012345678901234
32
32
  WALLET_ADDRESS=0x1234567890123456789012345678901234567890 # Optional - auto-derived
33
33
 
@@ -70,7 +70,7 @@ cp examples/claude-agent-x-follower/.env.example examples/claude-agent-x-followe
70
70
 
71
71
  ```env
72
72
  # Teneo Network Connection
73
- WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
73
+ WS_URL=wss://your-teneo-server.com/ws
74
74
  PRIVATE_KEY=0x1234567890123456789012345678901234567890123456789012345678901234
75
75
  WALLET_ADDRESS=0x1234567890123456789012345678901234567890 # Optional - auto-derived from private key
76
76
 
@@ -7,8 +7,8 @@
7
7
 
8
8
  # WebSocket URL for Teneo AI Network
9
9
  # Production: wss://your-production-server.com/ws
10
- # Development: wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
11
- WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
10
+ # Development: wss://your-teneo-server.com/ws
11
+ WS_URL=wss://your-teneo-server.com/ws
12
12
 
13
13
  # Ethereum Private Key (with 0x prefix)
14
14
  # IMPORTANT: Never commit your actual private key to version control!
@@ -76,7 +76,7 @@ cp .env.example .env
76
76
  nano .env # or your preferred editor
77
77
 
78
78
  # Required:
79
- # WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
79
+ # WS_URL=wss://your-teneo-server.com/ws
80
80
  # PRIVATE_KEY=0x...
81
81
  # WALLET_ADDRESS=0x... (optional - auto-derived from private key)
82
82
  # DEFAULT_ROOM=general (or x-agent-enterprise-v2 for X features)
@@ -18,8 +18,8 @@ OPENAI_MODEL=gpt-4-turbo-preview
18
18
 
19
19
  # WebSocket URL for Teneo AI Network
20
20
  # Production: wss://your-production-server.com/ws
21
- # Development: wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
22
- WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
21
+ # Development: wss://your-teneo-server.com/ws
22
+ WS_URL=wss://your-teneo-server.com/ws
23
23
 
24
24
  # Ethereum Private Key (with 0x prefix)
25
25
  # IMPORTANT: Never commit your actual private key to version control!
@@ -66,7 +66,7 @@ cp examples/openai-teneo/.env.example examples/openai-teneo/.env
66
66
  OPENAI_API_KEY=sk-proj-your-openai-api-key-here
67
67
 
68
68
  # Teneo Network Connection
69
- WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
69
+ WS_URL=wss://your-teneo-server.com/ws
70
70
  PRIVATE_KEY=0x1234567890123456789012345678901234567890123456789012345678901234
71
71
  WALLET_ADDRESS=0x1234567890123456789012345678901234567890 # Optional - auto-derived from private key
72
72
 
@@ -7,8 +7,8 @@
7
7
 
8
8
  # WebSocket URL for Teneo AI Network
9
9
  # Production: wss://your-production-server.com/ws
10
- # Development: wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
11
- WS_URL=wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws
10
+ # Development: wss://your-teneo-server.com/ws
11
+ WS_URL=wss://your-teneo-server.com/ws
12
12
 
13
13
  # Ethereum Private Key (with 0x prefix)
14
14
  # IMPORTANT: Never commit your actual private key to version control!
@@ -11,7 +11,9 @@ This is the **ultimate reference implementation** showcasing every SDK capabilit
11
11
  ✅ **WebSocket Connection** - Auto-reconnection with exponential backoff
12
12
  ✅ **Ethereum Authentication** - Wallet-based authentication
13
13
  ✅ **Message Sending** - Coordinator-based and direct agent commands
14
- ✅ **Room Management** - Subscribe, unsubscribe, and list rooms
14
+ ✅ **Room Management (v1)** - Subscribe, unsubscribe, and list rooms
15
+ ✅ **Room Management (v2.0)** - Create, update, delete rooms with ownership tracking
16
+ ✅ **Agent-Room Management (v2.0)** - Add/remove agents per room, list room agents
15
17
  ✅ **Agent Discovery** - List agents with capabilities
16
18
  ✅ **Response Formatting** - Raw JSON, humanized text, or both
17
19
 
@@ -29,6 +31,17 @@ This is the **ultimate reference implementation** showcasing every SDK capabilit
29
31
  ✅ **Error Handling** - Custom error classes with recovery strategies
30
32
  ✅ **Event System** - Complete event-driven architecture
31
33
 
34
+ ### v2.0 Features (New!)
35
+
36
+ ✅ **Multi-Room Management** - Create, update, and delete your own rooms
37
+ ✅ **Room Ownership Tracking** - Distinguish between owned and shared rooms
38
+ ✅ **Room Limits** - Track and display room creation quotas
39
+ ✅ **Agent-Room Customization** - Add/remove agents per room (owner only)
40
+ ✅ **Room Agent Listing** - List agents in specific rooms with caching
41
+ ✅ **Available Agents** - See which agents can be added to a room
42
+ ✅ **Real-time Room Events** - Live updates for room creation/updates/deletions
43
+ ✅ **Real-time Agent-Room Events** - Live updates when agents are added/removed
44
+
32
45
  ### Production Features
33
46
 
34
47
  ✅ **Health Check Endpoint** - `/health` for Kubernetes/Docker monitoring
@@ -205,15 +218,46 @@ const config = new SDKConfigBuilder()
205
218
  - `GET /api/agents/search/capability/:capability` - **PERF-3**: Search by capability (O(1))
206
219
  - `GET /api/agents/search/name/:name` - **PERF-3**: Search by name (O(k))
207
220
  - `GET /api/agents/search/status/:status` - **PERF-3**: Search by status (O(1))
208
- - `GET /api/rooms` - List all available rooms
221
+ - `GET /api/rooms` - List all available rooms (v1)
209
222
  - `GET /api/deduplication` - **CB-4**: Get message deduplication status
210
- - `POST /api/room/subscribe` - Subscribe to a room
223
+ - `POST /api/room/subscribe` - Subscribe to a room (v1)
211
224
  ```json
212
225
  {
213
226
  "roomId": "tech-support"
214
227
  }
215
228
  ```
216
- - `POST /api/room/unsubscribe` - Unsubscribe from a room
229
+ - `POST /api/room/unsubscribe` - Unsubscribe from a room (v1)
230
+
231
+ ### Room Management v2.0 API
232
+
233
+ - `GET /api/v2/rooms/owned` - Get all rooms you own
234
+ - `GET /api/v2/rooms/shared` - Get all rooms you're a member of
235
+ - `GET /api/v2/rooms/limit` - Get your room creation limit
236
+ - `POST /api/v2/rooms` - Create a new room
237
+ ```json
238
+ {
239
+ "name": "My Room",
240
+ "description": "Optional description"
241
+ }
242
+ ```
243
+ - `PUT /api/v2/rooms/:id` - Update room (owner only)
244
+ ```json
245
+ {
246
+ "name": "Updated Name",
247
+ "description": "New description"
248
+ }
249
+ ```
250
+ - `DELETE /api/v2/rooms/:id` - Delete room (owner only)
251
+
252
+ ### Agent-Room Management v2.0 API
253
+
254
+ - `GET /api/v2/rooms/:id/agents` - List agents in room (with 5-min cache)
255
+ - `GET /api/v2/rooms/:id/available-agents` - List agents available to add
256
+ - `GET /api/v2/rooms/:id/agents/count` - Get agent count (instant, from cache)
257
+ - `GET /api/v2/rooms/:roomId/agents/:agentId/check` - Check if agent is in room
258
+ - `POST /api/v2/rooms/:roomId/agents/:agentId` - Add agent to room (owner only)
259
+ - `DELETE /api/v2/rooms/:roomId/agents/:agentId` - Remove agent from room (owner only)
260
+ - `POST /api/v2/rooms/:id/cache/invalidate` - Manually invalidate agent-room cache
217
261
 
218
262
  ### Real-time Data
219
263
 
@@ -240,10 +284,12 @@ const config = new SDKConfigBuilder()
240
284
  ### Tabs
241
285
 
242
286
  1. **Agents Tab**: List all agents with capabilities and status
243
- 2. **Rooms Tab**: Manage room subscriptions (subscribe/unsubscribe)
244
- 3. **Messages Tab**: View message history with responses
245
- 4. **Webhooks Tab**: Monitor received webhooks
246
- 5. **Events Tab**: Real-time event stream
287
+ 2. **Rooms Tab**: Manage room subscriptions (subscribe/unsubscribe) - v1
288
+ 3. **Room Mgmt Tab** 🆕: Create, update, delete rooms - View owned/shared rooms with room limits (v2.0)
289
+ 4. **Agent-Room Tab** 🆕: Add/remove agents to rooms - List room agents and available agents (v2.0)
290
+ 5. **Messages Tab**: View message history with responses
291
+ 6. **Webhooks Tab**: Monitor received webhooks
292
+ 7. **Events Tab**: Real-time event stream (includes v2.0 room and agent-room events)
247
293
 
248
294
  ### Health Monitor
249
295
 
@@ -265,18 +311,18 @@ import { SecurePrivateKey } from "@teneo-protocol/sdk";
265
311
  const secureKey = new SecurePrivateKey(process.env.PRIVATE_KEY);
266
312
 
267
313
  // Use with SDK - automatically decrypted when needed
268
- const config = new SDKConfigBuilder()
269
- .withAuthentication(secureKey, WALLET_ADDRESS)
270
- .build();
314
+ const config = new SDKConfigBuilder().withAuthentication(secureKey, WALLET_ADDRESS).build();
271
315
  ```
272
316
 
273
317
  **Security Benefits:**
318
+
274
319
  - Private key is encrypted in memory using AES-256-GCM
275
320
  - Protected from memory dumps and debugging tools
276
321
  - Automatic secure cleanup when no longer needed
277
322
  - Minimal performance overhead
278
323
 
279
324
  **Example Test:**
325
+
280
326
  ```bash
281
327
  # Without encryption: private key visible in memory dump
282
328
  # With encryption: only encrypted bytes visible
@@ -298,17 +344,20 @@ Prevent duplicate message processing using a TTL-based cache:
298
344
  ```
299
345
 
300
346
  **How It Works:**
347
+
301
348
  - Maintains an in-memory cache of processed message IDs
302
349
  - Automatically expires entries after TTL (Time To Live)
303
350
  - Bounded size prevents unbounded memory growth
304
351
  - Messages without IDs are allowed through (graceful degradation)
305
352
 
306
353
  **Configuration Options:**
354
+
307
355
  - `enabled`: Enable/disable deduplication (default: true)
308
356
  - `ttl`: How long to remember message IDs in milliseconds (default: 60000ms = 1 minute)
309
357
  - `maxSize`: Maximum number of message IDs to cache (default: 10000)
310
358
 
311
359
  **Monitoring:**
360
+
312
361
  ```bash
313
362
  # Check deduplication status
314
363
  curl http://localhost:3000/api/deduplication
@@ -324,15 +373,18 @@ curl http://localhost:3000/api/deduplication
324
373
  ```
325
374
 
326
375
  **Events:**
376
+
327
377
  - `message:duplicate` - Emitted when a duplicate message is detected and skipped
328
378
 
329
379
  **Testing:**
380
+
330
381
  1. Send the same message multiple times rapidly
331
382
  2. Watch Events tab for `message:duplicate` events
332
383
  3. Verify duplicates are not processed
333
384
  4. Monitor `/api/deduplication` to see cache size increase
334
385
 
335
386
  **Production Benefits:**
387
+
336
388
  - Prevents duplicate task execution if messages are retransmitted
337
389
  - Protects against network-level duplicates during reconnections
338
390
  - Configurable TTL balances memory usage vs duplicate window
@@ -354,11 +406,13 @@ curl http://localhost:3000/api/agents/search/status/online
354
406
  ```
355
407
 
356
408
  **Performance Comparison:**
409
+
357
410
  - Traditional: O(n) - iterate through all agents
358
411
  - Indexed: O(1) - direct map lookup for capability/status
359
412
  - Indexed: O(k) - token-based search for names (k = tokens)
360
413
 
361
414
  **SDK Usage:**
415
+
362
416
  ```typescript
363
417
  // Fast capability search
364
418
  const weatherAgents = sdk.findAgentsByCapability("weather-forecast");
@@ -524,7 +578,7 @@ Monitor rate limit status via `/metrics` endpoint.
524
578
  - Watch Webhooks tab for incoming webhook events
525
579
  - See event types: `task`, `agent_selected`, `task_response`
526
580
 
527
- ### 5. Test Room Management
581
+ ### 5. Test Room Management (v1)
528
582
 
529
583
  - Go to Rooms tab
530
584
  - Enter a room ID
@@ -532,6 +586,29 @@ Monitor rate limit status via `/metrics` endpoint.
532
586
  - See room appear in subscribed list
533
587
  - Click "Unsubscribe" to unsubscribe from room
534
588
 
589
+ ### 5b. Test Room Management v2.0
590
+
591
+ - Go to **Room Mgmt** tab
592
+ - See your owned and shared rooms
593
+ - Check your room limit (e.g., "2/50 rooms")
594
+ - **Create a room**: Enter name and description, click "Create Room"
595
+ - See room appear in "Private Rooms" list with owner badge
596
+ - **Update room**: Click "Update" on an owned room, modify name/description
597
+ - **Delete room**: Click "Delete" on an owned room
598
+ - Watch Events tab for `room:created`, `room:updated`, `room:deleted` events
599
+
600
+ ### 5c. Test Agent-Room Management v2.0
601
+
602
+ - Go to **Agent-Room** tab
603
+ - Select a room you own from the dropdown
604
+ - See "Agents in Room" list (may be empty for new rooms)
605
+ - See "Available Agents" list (agents you can add)
606
+ - **Add an agent**: Click "Add" next to an available agent
607
+ - Watch agent move from "Available" to "Agents in Room"
608
+ - See agent count update in real-time
609
+ - **Remove an agent**: Click "Remove" next to an agent in room
610
+ - Watch Events tab for `agent_room:agent_added`, `agent_room:agent_removed` events
611
+
535
612
  ### 6. Test Signature Verification
536
613
 
537
614
  - Enable in `.env`: `ENABLE_SIGNATURE_VERIFICATION=true`