@teneo-protocol/sdk 2.2.2 → 3.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 (228) hide show
  1. package/.github/ISSUE_TEMPLATE/config.yml +1 -1
  2. package/CHANGELOG.md +366 -15
  3. package/CONCEPTS.md +182 -44
  4. package/README.md +524 -94
  5. package/dist/constants.d.ts +3 -1
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +5 -3
  8. package/dist/constants.js.map +1 -1
  9. package/dist/core/websocket-client.d.ts.map +1 -1
  10. package/dist/core/websocket-client.js +9 -5
  11. package/dist/core/websocket-client.js.map +1 -1
  12. package/dist/formatters/response-formatter.d.ts +6 -6
  13. package/dist/handlers/message-handlers/agent-details-response-handler.d.ts +756 -756
  14. package/dist/handlers/message-handlers/agent-details-response-handler.js +2 -2
  15. package/dist/handlers/message-handlers/agent-details-response-handler.js.map +1 -1
  16. package/dist/handlers/message-handlers/agent-error-handler.d.ts +91 -0
  17. package/dist/handlers/message-handlers/agent-error-handler.d.ts.map +1 -0
  18. package/dist/handlers/message-handlers/agent-error-handler.js +44 -0
  19. package/dist/handlers/message-handlers/agent-error-handler.js.map +1 -0
  20. package/dist/handlers/message-handlers/agent-selected-handler.d.ts +6 -0
  21. package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
  22. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +756 -756
  23. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -1
  24. package/dist/handlers/message-handlers/agent-status-update-handler.js +2 -7
  25. package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -1
  26. package/dist/handlers/message-handlers/all-agents-response-handler.js +2 -2
  27. package/dist/handlers/message-handlers/all-agents-response-handler.js.map +1 -1
  28. package/dist/handlers/message-handlers/auth-error-handler.d.ts +6 -0
  29. package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
  30. package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
  31. package/dist/handlers/message-handlers/auth-message-handler.js +6 -1
  32. package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
  33. package/dist/handlers/message-handlers/auth-required-handler.d.ts +6 -0
  34. package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
  35. package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
  36. package/dist/handlers/message-handlers/auth-success-handler.js +6 -1
  37. package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
  38. package/dist/handlers/message-handlers/base-handler.d.ts +2 -1
  39. package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -1
  40. package/dist/handlers/message-handlers/base-handler.js +24 -4
  41. package/dist/handlers/message-handlers/base-handler.js.map +1 -1
  42. package/dist/handlers/message-handlers/challenge-handler.d.ts +6 -0
  43. package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
  44. package/dist/handlers/message-handlers/error-message-handler.d.ts +6 -0
  45. package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
  46. package/dist/handlers/message-handlers/index.d.ts +4 -0
  47. package/dist/handlers/message-handlers/index.d.ts.map +1 -1
  48. package/dist/handlers/message-handlers/index.js +23 -1
  49. package/dist/handlers/message-handlers/index.js.map +1 -1
  50. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +792 -756
  51. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -1
  52. package/dist/handlers/message-handlers/list-available-agents-handler.js +23 -10
  53. package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -1
  54. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +756 -756
  55. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -1
  56. package/dist/handlers/message-handlers/list-room-agents-handler.js +2 -6
  57. package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -1
  58. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
  59. package/dist/handlers/message-handlers/list-rooms-response-handler.js +2 -5
  60. package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -1
  61. package/dist/handlers/message-handlers/ping-pong-handler.d.ts +52 -4
  62. package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
  63. package/dist/handlers/message-handlers/ping-pong-handler.js +23 -4
  64. package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -1
  65. package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts.map +1 -1
  66. package/dist/handlers/message-handlers/rate-limit-notification-handler.js +3 -2
  67. package/dist/handlers/message-handlers/rate-limit-notification-handler.js.map +1 -1
  68. package/dist/handlers/message-handlers/regular-message-handler.d.ts +6 -0
  69. package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
  70. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +12 -6
  71. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
  72. package/dist/handlers/message-handlers/success-handler.d.ts +82 -0
  73. package/dist/handlers/message-handlers/success-handler.d.ts.map +1 -0
  74. package/dist/handlers/message-handlers/success-handler.js +24 -0
  75. package/dist/handlers/message-handlers/success-handler.js.map +1 -0
  76. package/dist/handlers/message-handlers/task-confirmed-handler.d.ts +110 -0
  77. package/dist/handlers/message-handlers/task-confirmed-handler.d.ts.map +1 -0
  78. package/dist/handlers/message-handlers/task-confirmed-handler.js +46 -0
  79. package/dist/handlers/message-handlers/task-confirmed-handler.js.map +1 -0
  80. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts +244 -0
  81. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts.map +1 -0
  82. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js +58 -0
  83. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js.map +1 -0
  84. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +12 -6
  85. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
  86. package/dist/handlers/message-handlers/user-authenticated-handler.js +2 -2
  87. package/dist/handlers/message-handlers/user-authenticated-handler.js.map +1 -1
  88. package/dist/handlers/message-handlers/user-count-handler.js +2 -2
  89. package/dist/handlers/message-handlers/user-count-handler.js.map +1 -1
  90. package/dist/index.d.ts +3 -3
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +11 -4
  93. package/dist/index.js.map +1 -1
  94. package/dist/managers/admin-manager.d.ts +2 -0
  95. package/dist/managers/admin-manager.d.ts.map +1 -1
  96. package/dist/managers/admin-manager.js +3 -2
  97. package/dist/managers/admin-manager.js.map +1 -1
  98. package/dist/managers/agent-room-manager.d.ts +89 -11
  99. package/dist/managers/agent-room-manager.d.ts.map +1 -1
  100. package/dist/managers/agent-room-manager.js +99 -35
  101. package/dist/managers/agent-room-manager.js.map +1 -1
  102. package/dist/managers/index.d.ts +1 -1
  103. package/dist/managers/index.d.ts.map +1 -1
  104. package/dist/managers/index.js.map +1 -1
  105. package/dist/managers/message-router.d.ts +45 -5
  106. package/dist/managers/message-router.d.ts.map +1 -1
  107. package/dist/managers/message-router.js +96 -24
  108. package/dist/managers/message-router.js.map +1 -1
  109. package/dist/managers/room-manager.d.ts +29 -7
  110. package/dist/managers/room-manager.d.ts.map +1 -1
  111. package/dist/managers/room-manager.js +37 -11
  112. package/dist/managers/room-manager.js.map +1 -1
  113. package/dist/payments/index.d.ts +3 -1
  114. package/dist/payments/index.d.ts.map +1 -1
  115. package/dist/payments/index.js +17 -3
  116. package/dist/payments/index.js.map +1 -1
  117. package/dist/payments/networks.d.ts +59 -0
  118. package/dist/payments/networks.d.ts.map +1 -0
  119. package/dist/payments/networks.js +192 -0
  120. package/dist/payments/networks.js.map +1 -0
  121. package/dist/payments/payment-client.d.ts +55 -10
  122. package/dist/payments/payment-client.d.ts.map +1 -1
  123. package/dist/payments/payment-client.js +172 -51
  124. package/dist/payments/payment-client.js.map +1 -1
  125. package/dist/teneo-sdk.d.ts +214 -40
  126. package/dist/teneo-sdk.d.ts.map +1 -1
  127. package/dist/teneo-sdk.js +360 -83
  128. package/dist/teneo-sdk.js.map +1 -1
  129. package/dist/types/config.d.ts +334 -25
  130. package/dist/types/config.d.ts.map +1 -1
  131. package/dist/types/config.js +114 -22
  132. package/dist/types/config.js.map +1 -1
  133. package/dist/types/events.d.ts +60 -14
  134. package/dist/types/events.d.ts.map +1 -1
  135. package/dist/types/events.js.map +1 -1
  136. package/dist/types/index.d.ts +1 -1
  137. package/dist/types/index.d.ts.map +1 -1
  138. package/dist/types/index.js +11 -4
  139. package/dist/types/index.js.map +1 -1
  140. package/dist/types/messages.d.ts +9801 -7222
  141. package/dist/types/messages.d.ts.map +1 -1
  142. package/dist/types/messages.js +180 -40
  143. package/dist/types/messages.js.map +1 -1
  144. package/dist/utils/pricing-resolver.d.ts +1 -1
  145. package/dist/utils/pricing-resolver.d.ts.map +1 -1
  146. package/dist/utils/pricing-resolver.js +9 -1
  147. package/dist/utils/pricing-resolver.js.map +1 -1
  148. package/examples/agent-room-management-example.ts +5 -5
  149. package/examples/basic-usage.ts +26 -6
  150. package/examples/claude-agent-x-follower/index.ts +1 -1
  151. package/examples/minimal-chat.ts +4 -3
  152. package/examples/n8n-teneo/index.ts +2 -2
  153. package/examples/nestjs-dashboard/README.md +1 -1
  154. package/examples/nestjs-dashboard/src/teneo/agents.controller.ts +3 -3
  155. package/examples/nestjs-dashboard/src/teneo/rooms.controller.ts +5 -5
  156. package/examples/nestjs-dashboard/src/teneo/teneo.service.ts +8 -8
  157. package/examples/openai-teneo/index.ts +1 -1
  158. package/examples/payment-flow.ts +143 -0
  159. package/examples/production-dashboard/README.md +6 -8
  160. package/examples/production-dashboard/server.ts +22 -10
  161. package/examples/room-management-example.ts +2 -2
  162. package/examples/usage/01-connect.ts +0 -3
  163. package/examples/usage/02-list-agents.ts +0 -2
  164. package/examples/usage/03-pick-agent.ts +3 -4
  165. package/examples/usage/04-find-by-capability.ts +10 -12
  166. package/examples/usage/05-webhook-example.ts +2 -4
  167. package/examples/usage/06-simple-api-server.ts +13 -9
  168. package/examples/usage/07-event-listener.ts +1 -13
  169. package/examples/usage/README.md +33 -7
  170. package/examples/webhook-integration.ts +9 -9
  171. package/examples/x-influencer-battle-server.ts +1 -1
  172. package/package.json +1 -1
  173. package/scripts/diagnose-connection.ts +86 -0
  174. package/scripts/investigate-payload.ts +163 -0
  175. package/scripts/list-agents.ts +58 -0
  176. package/scripts/live-multi-network-test.ts +230 -0
  177. package/src/constants.ts +5 -3
  178. package/src/core/websocket-client.ts +10 -9
  179. package/src/handlers/message-handlers/agent-details-response-handler.ts +2 -2
  180. package/src/handlers/message-handlers/agent-error-handler.ts +47 -0
  181. package/src/handlers/message-handlers/agent-status-update-handler.ts +2 -7
  182. package/src/handlers/message-handlers/all-agents-response-handler.ts +2 -2
  183. package/src/handlers/message-handlers/auth-message-handler.ts +7 -1
  184. package/src/handlers/message-handlers/auth-success-handler.ts +7 -1
  185. package/src/handlers/message-handlers/base-handler.ts +24 -4
  186. package/src/handlers/message-handlers/index.ts +24 -0
  187. package/src/handlers/message-handlers/list-available-agents-handler.ts +24 -11
  188. package/src/handlers/message-handlers/list-room-agents-handler.ts +2 -6
  189. package/src/handlers/message-handlers/list-rooms-response-handler.ts +2 -5
  190. package/src/handlers/message-handlers/ping-pong-handler.ts +29 -4
  191. package/src/handlers/message-handlers/rate-limit-notification-handler.ts +3 -2
  192. package/src/handlers/message-handlers/success-handler.ts +26 -0
  193. package/src/handlers/message-handlers/task-confirmed-handler.ts +49 -0
  194. package/src/handlers/message-handlers/trigger-wallet-tx-handler.ts +62 -0
  195. package/src/handlers/message-handlers/user-authenticated-handler.ts +2 -2
  196. package/src/handlers/message-handlers/user-count-handler.ts +2 -2
  197. package/src/index.ts +12 -4
  198. package/src/managers/admin-manager.ts +5 -2
  199. package/src/managers/agent-room-manager.ts +155 -26
  200. package/src/managers/index.ts +6 -1
  201. package/src/managers/message-router.ts +122 -27
  202. package/src/managers/room-manager.ts +39 -11
  203. package/src/payments/index.ts +20 -5
  204. package/src/payments/networks.ts +208 -0
  205. package/src/payments/payment-client.ts +211 -56
  206. package/src/teneo-sdk.ts +401 -70
  207. package/src/types/config.test.ts +24 -4
  208. package/src/types/config.ts +123 -25
  209. package/src/types/events.ts +36 -2
  210. package/src/types/index.ts +16 -3
  211. package/src/types/messages.ts +221 -57
  212. package/src/utils/pricing-resolver.ts +10 -2
  213. package/tests/direct-agent-test.ts +1 -1
  214. package/tests/integration/real-server.test.ts +1 -1
  215. package/tests/integration/websocket.test.ts +3 -3
  216. package/tests/multi-network-payment.test.ts +309 -0
  217. package/tests/multi-network.test.ts +296 -0
  218. package/tests/payment-flow-test.ts +6 -4
  219. package/tests/unit/handlers/agent-error-handler.test.ts +388 -0
  220. package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +9 -6
  221. package/tests/unit/handlers/agent-status-update-handler.test.ts +11 -16
  222. package/tests/unit/handlers/list-available-agents-handler.test.ts +11 -14
  223. package/tests/unit/handlers/list-room-agents-handler.test.ts +11 -15
  224. package/tests/unit/handlers/room-operation-response-handler.test.ts +9 -6
  225. package/tests/unit/handlers/trigger-wallet-tx-handler.test.ts +431 -0
  226. package/tests/unit/managers/admin-manager.test.ts +183 -0
  227. package/tests/unit/managers/agent-room-manager.test.ts +189 -33
  228. package/tests/unit/sdk-new-methods.test.ts +221 -0
@@ -4,7 +4,11 @@
4
4
  */
5
5
 
6
6
  import { describe, it, expect, beforeEach, vi } from "vitest";
7
- import { AgentRoomManager, AgentRoomInfo } from "../../../src/managers/agent-room-manager";
7
+ import {
8
+ AgentRoomManager,
9
+ AgentRoomInfo,
10
+ PaginatedAgentsResult
11
+ } from "../../../src/managers/agent-room-manager";
8
12
  import { RoomManagementManager } from "../../../src/managers/room-management-manager";
9
13
  import { WebSocketClient } from "../../../src/core/websocket-client";
10
14
  import { Logger, RoomInfo } from "../../../src/types";
@@ -126,7 +130,7 @@ describe("AgentRoomManager", () => {
126
130
  const cachedAgents: AgentRoomInfo[] = [{ agent_id: "agent-1", agent_name: "Agent 1" }];
127
131
  manager.cacheRoomAgents("room-123", cachedAgents);
128
132
 
129
- expect(manager.getRoomAgents("room-123")).toHaveLength(1);
133
+ expect(manager.getCachedRoomAgents("room-123")).toHaveLength(1);
130
134
 
131
135
  const addPromise = manager.addAgentToRoom("room-123", "agent-456");
132
136
 
@@ -137,7 +141,7 @@ describe("AgentRoomManager", () => {
137
141
  await addPromise;
138
142
 
139
143
  // Cache should be invalidated
140
- expect(manager.getRoomAgents("room-123")).toBeUndefined();
144
+ expect(manager.getCachedRoomAgents("room-123")).toBeUndefined();
141
145
  });
142
146
  });
143
147
 
@@ -205,7 +209,7 @@ describe("AgentRoomManager", () => {
205
209
  const cachedAgents: AgentRoomInfo[] = [{ agent_id: "agent-456", agent_name: "Agent 456" }];
206
210
  manager.cacheRoomAgents("room-123", cachedAgents);
207
211
 
208
- expect(manager.getRoomAgents("room-123")).toHaveLength(1);
212
+ expect(manager.getCachedRoomAgents("room-123")).toHaveLength(1);
209
213
 
210
214
  const removePromise = manager.removeAgentFromRoom("room-123", "agent-456");
211
215
 
@@ -216,7 +220,7 @@ describe("AgentRoomManager", () => {
216
220
  await removePromise;
217
221
 
218
222
  // Cache should be invalidated
219
- expect(manager.getRoomAgents("room-123")).toBeUndefined();
223
+ expect(manager.getCachedRoomAgents("room-123")).toBeUndefined();
220
224
  });
221
225
  });
222
226
 
@@ -374,50 +378,50 @@ describe("AgentRoomManager", () => {
374
378
  it("should get room agents from cache", () => {
375
379
  manager.cacheRoomAgents("room-123", mockAgents);
376
380
 
377
- const result = manager.getRoomAgents("room-123");
381
+ const result = manager.getCachedRoomAgents("room-123");
378
382
 
379
383
  expect(result).toHaveLength(2);
380
384
  expect(result![0].agent_id).toBe("agent-1");
381
385
  });
382
386
 
383
387
  it("should return undefined if room agents not cached", () => {
384
- const result = manager.getRoomAgents("room-999");
388
+ const result = manager.getCachedRoomAgents("room-999");
385
389
  expect(result).toBeUndefined();
386
390
  });
387
391
 
388
392
  it("should get available agents from cache", () => {
389
393
  manager.cacheAvailableAgents("room-123", mockAgents);
390
394
 
391
- const result = manager.getAvailableAgents("room-123");
395
+ const result = manager.getCachedAvailableAgents("room-123");
392
396
 
393
397
  expect(result).toHaveLength(2);
394
398
  expect(result![0].agent_id).toBe("agent-1");
395
399
  });
396
400
 
397
401
  it("should return undefined if available agents not cached", () => {
398
- const result = manager.getAvailableAgents("room-999");
402
+ const result = manager.getCachedAvailableAgents("room-999");
399
403
  expect(result).toBeUndefined();
400
404
  });
401
405
 
402
406
  it("should check if agent is in room", () => {
403
407
  manager.cacheRoomAgents("room-123", mockAgents);
404
408
 
405
- expect(manager.isAgentInRoom("room-123", "agent-1")).toBe(true);
406
- expect(manager.isAgentInRoom("room-123", "agent-999")).toBe(false);
409
+ expect(manager.checkAgentInRoom("room-123", "agent-1")).toBe(true);
410
+ expect(manager.checkAgentInRoom("room-123", "agent-999")).toBe(false);
407
411
  });
408
412
 
409
- it("should return undefined for isAgentInRoom if not cached", () => {
410
- expect(manager.isAgentInRoom("room-999", "agent-1")).toBeUndefined();
413
+ it("should return undefined for checkAgentInRoom if not cached", () => {
414
+ expect(manager.checkAgentInRoom("room-999", "agent-1")).toBeUndefined();
411
415
  });
412
416
 
413
417
  it("should get room agent count", () => {
414
418
  manager.cacheRoomAgents("room-123", mockAgents);
415
419
 
416
- expect(manager.getRoomAgentCount("room-123")).toBe(2);
420
+ expect(manager.getCachedRoomAgentCount("room-123")).toBe(2);
417
421
  });
418
422
 
419
423
  it("should return undefined for count if not cached", () => {
420
- expect(manager.getRoomAgentCount("room-999")).toBeUndefined();
424
+ expect(manager.getCachedRoomAgentCount("room-999")).toBeUndefined();
421
425
  });
422
426
  });
423
427
 
@@ -427,7 +431,7 @@ describe("AgentRoomManager", () => {
427
431
  it("should cache room agents", () => {
428
432
  manager.cacheRoomAgents("room-123", mockAgents);
429
433
 
430
- const result = manager.getRoomAgents("room-123");
434
+ const result = manager.getCachedRoomAgents("room-123");
431
435
  expect(result).toHaveLength(1);
432
436
  expect(result![0].agent_id).toBe("agent-1");
433
437
  });
@@ -435,7 +439,7 @@ describe("AgentRoomManager", () => {
435
439
  it("should cache available agents", () => {
436
440
  manager.cacheAvailableAgents("room-123", mockAgents);
437
441
 
438
- const result = manager.getAvailableAgents("room-123");
442
+ const result = manager.getCachedAvailableAgents("room-123");
439
443
  expect(result).toHaveLength(1);
440
444
  });
441
445
 
@@ -446,9 +450,9 @@ describe("AgentRoomManager", () => {
446
450
 
447
451
  manager.invalidateCache("room-123");
448
452
 
449
- expect(manager.getRoomAgents("room-123")).toBeUndefined();
450
- expect(manager.getAvailableAgents("room-123")).toBeUndefined();
451
- expect(manager.getRoomAgents("room-456")).toBeDefined();
453
+ expect(manager.getCachedRoomAgents("room-123")).toBeUndefined();
454
+ expect(manager.getCachedAvailableAgents("room-123")).toBeUndefined();
455
+ expect(manager.getCachedRoomAgents("room-456")).toBeDefined();
452
456
  });
453
457
 
454
458
  it("should clear all caches", () => {
@@ -458,9 +462,9 @@ describe("AgentRoomManager", () => {
458
462
 
459
463
  manager.clearAllCaches();
460
464
 
461
- expect(manager.getRoomAgents("room-123")).toBeUndefined();
462
- expect(manager.getRoomAgents("room-456")).toBeUndefined();
463
- expect(manager.getAvailableAgents("room-123")).toBeUndefined();
465
+ expect(manager.getCachedRoomAgents("room-123")).toBeUndefined();
466
+ expect(manager.getCachedRoomAgents("room-456")).toBeUndefined();
467
+ expect(manager.getCachedAvailableAgents("room-123")).toBeUndefined();
464
468
  });
465
469
  });
466
470
 
@@ -472,12 +476,12 @@ describe("AgentRoomManager", () => {
472
476
  it("should handle status updates and invalidate cache", () => {
473
477
  manager.cacheRoomAgents("room-123", mockAgents);
474
478
 
475
- expect(manager.getRoomAgents("room-123")).toBeDefined();
479
+ expect(manager.getCachedRoomAgents("room-123")).toBeDefined();
476
480
 
477
481
  manager.handleStatusUpdate("room-123", "agent-1", "offline");
478
482
 
479
483
  // Cache should be invalidated
480
- expect(manager.getRoomAgents("room-123")).toBeUndefined();
484
+ expect(manager.getCachedRoomAgents("room-123")).toBeUndefined();
481
485
  });
482
486
 
483
487
  it("should not invalidate other room caches on status update", () => {
@@ -486,29 +490,181 @@ describe("AgentRoomManager", () => {
486
490
 
487
491
  manager.handleStatusUpdate("room-123", "agent-1", "offline");
488
492
 
489
- expect(manager.getRoomAgents("room-123")).toBeUndefined();
490
- expect(manager.getRoomAgents("room-456")).toBeDefined();
493
+ expect(manager.getCachedRoomAgents("room-123")).toBeUndefined();
494
+ expect(manager.getCachedRoomAgents("room-456")).toBeDefined();
495
+ });
496
+ });
497
+
498
+ describe("listAvailableAgents with pagination", () => {
499
+ const mockAgents: AgentRoomInfo[] = [
500
+ { agent_id: "agent-3", agent_name: "Agent 3", status: "online" },
501
+ { agent_id: "agent-4", agent_name: "Agent 4", status: "online" }
502
+ ];
503
+
504
+ it("should send pagination params in the message data", async () => {
505
+ const listPromise = manager.listAvailableAgents("room-123", {
506
+ limit: 20,
507
+ offset: 10,
508
+ sortBy: "a-z"
509
+ });
510
+
511
+ setTimeout(() => {
512
+ manager.emit("agent_room:available_agents_listed", mockAgents, {
513
+ total: 100,
514
+ offset: 10,
515
+ limit: 20,
516
+ hasMore: true
517
+ });
518
+ }, 10);
519
+
520
+ await listPromise;
521
+
522
+ expect(mockWsClient.sendMessage).toHaveBeenCalledWith({
523
+ type: "list_available_agents",
524
+ data: {
525
+ room_id: "room-123",
526
+ limit: 20,
527
+ offset: 10,
528
+ sort_by: "a-z"
529
+ }
530
+ });
531
+ });
532
+
533
+ it("should return PaginatedAgentsResult when called with options", async () => {
534
+ const listPromise = manager.listAvailableAgents("room-123", {
535
+ limit: 20,
536
+ offset: 10
537
+ });
538
+
539
+ setTimeout(() => {
540
+ manager.emit("agent_room:available_agents_listed", mockAgents, {
541
+ total: 100,
542
+ offset: 10,
543
+ limit: 20,
544
+ hasMore: true
545
+ });
546
+ }, 10);
547
+
548
+ const result = await listPromise;
549
+
550
+ expect(result).toEqual({
551
+ agents: mockAgents,
552
+ total: 100,
553
+ offset: 10,
554
+ limit: 20,
555
+ hasMore: true
556
+ } satisfies PaginatedAgentsResult);
557
+ });
558
+
559
+ it("should not use cache when called with options object", async () => {
560
+ // Pre-populate cache
561
+ manager.cacheAvailableAgents("room-123", mockAgents);
562
+
563
+ // Verify cache has data
564
+ expect(manager.getCachedAvailableAgents("room-123")).toHaveLength(2);
565
+
566
+ const listPromise = manager.listAvailableAgents("room-123", { limit: 10 });
567
+
568
+ setTimeout(() => {
569
+ manager.emit("agent_room:available_agents_listed", mockAgents, {
570
+ total: 2,
571
+ offset: 0,
572
+ limit: 10,
573
+ hasMore: false
574
+ });
575
+ }, 10);
576
+
577
+ await listPromise;
578
+
579
+ // Should have sent a message to the server despite cache existing
580
+ expect(mockWsClient.sendMessage).toHaveBeenCalledWith(
581
+ expect.objectContaining({ type: "list_available_agents" })
582
+ );
583
+ });
584
+
585
+ it("should send all option fields with correct snake_case mapping", async () => {
586
+ const listPromise = manager.listAvailableAgents("room-123", {
587
+ limit: 50,
588
+ offset: 0,
589
+ includeDetails: true,
590
+ minimal: false,
591
+ sortBy: "requests",
592
+ includeInRoom: true
593
+ });
594
+
595
+ setTimeout(() => {
596
+ manager.emit("agent_room:available_agents_listed", mockAgents, {
597
+ total: 2,
598
+ offset: 0,
599
+ limit: 50,
600
+ hasMore: false
601
+ });
602
+ }, 10);
603
+
604
+ await listPromise;
605
+
606
+ expect(mockWsClient.sendMessage).toHaveBeenCalledWith({
607
+ type: "list_available_agents",
608
+ data: {
609
+ room_id: "room-123",
610
+ limit: 50,
611
+ offset: 0,
612
+ include_details: true,
613
+ minimal: false,
614
+ sort_by: "requests",
615
+ include_in_room: true
616
+ }
617
+ });
618
+ });
619
+
620
+ it("should maintain backward compatibility with boolean useCache parameter", async () => {
621
+ const listPromise = manager.listAvailableAgents("room-123", true);
622
+
623
+ // Pre-populate cache is not set, so it will send a message
624
+ // But if we set cache first and call with true, it should use cache
625
+ manager.cacheAvailableAgents("room-123", mockAgents);
626
+
627
+ const cachedResult = await manager.listAvailableAgents("room-123", true);
628
+
629
+ // Should return AgentRoomInfo[] (not PaginatedAgentsResult)
630
+ expect(Array.isArray(cachedResult)).toBe(true);
631
+ expect(cachedResult).toHaveLength(2);
632
+ expect((cachedResult as AgentRoomInfo[])[0].agent_id).toBe("agent-3");
633
+
634
+ // The first call (no cache) should have triggered sendMessage
635
+ setTimeout(() => {
636
+ manager.emit("agent_room:available_agents_listed", mockAgents);
637
+ }, 10);
638
+
639
+ const result = await listPromise;
640
+
641
+ // Legacy call returns AgentRoomInfo[], not PaginatedAgentsResult
642
+ expect(Array.isArray(result)).toBe(true);
643
+ expect(result as AgentRoomInfo[]).toHaveLength(2);
644
+ // Should NOT have 'total', 'offset', 'limit', 'hasMore' properties
645
+ expect(result).not.toHaveProperty("total");
646
+ expect(result).not.toHaveProperty("hasMore");
491
647
  });
492
648
  });
493
649
 
494
650
  describe("Return Value Immutability", () => {
495
651
  const mockAgents: AgentRoomInfo[] = [{ agent_id: "agent-1", agent_name: "Agent 1" }];
496
652
 
497
- it("should return defensive copies from getRoomAgents", () => {
653
+ it("should return defensive copies from getCachedRoomAgents", () => {
498
654
  manager.cacheRoomAgents("room-123", mockAgents);
499
655
 
500
- const agents1 = manager.getRoomAgents("room-123");
501
- const agents2 = manager.getRoomAgents("room-123");
656
+ const agents1 = manager.getCachedRoomAgents("room-123");
657
+ const agents2 = manager.getCachedRoomAgents("room-123");
502
658
 
503
659
  expect(agents1).not.toBe(agents2);
504
660
  expect(agents1![0]).not.toBe(agents2![0]);
505
661
  });
506
662
 
507
- it("should return defensive copies from getAvailableAgents", () => {
663
+ it("should return defensive copies from getCachedAvailableAgents", () => {
508
664
  manager.cacheAvailableAgents("room-123", mockAgents);
509
665
 
510
- const agents1 = manager.getAvailableAgents("room-123");
511
- const agents2 = manager.getAvailableAgents("room-123");
666
+ const agents1 = manager.getCachedAvailableAgents("room-123");
667
+ const agents2 = manager.getCachedAvailableAgents("room-123");
512
668
 
513
669
  expect(agents1).not.toBe(agents2);
514
670
  expect(agents1![0]).not.toBe(agents2![0]);
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Unit tests for TeneoSDK.setApiKeyPreference() and TeneoSDK.sendTxResult()
3
+ * Tests message shape, destroyed state, and connection state checks
4
+ */
5
+
6
+ import { describe, it, expect, beforeEach, vi } from "vitest";
7
+ import { TeneoSDK } from "../../src/teneo-sdk";
8
+ import { ErrorCode } from "../../src/types/error-codes";
9
+
10
+ describe("TeneoSDK New Methods", () => {
11
+ let sdk: TeneoSDK;
12
+ let sendMessageSpy: ReturnType<typeof vi.fn>;
13
+ let mockWsClient: { isConnected: boolean; sendMessage: ReturnType<typeof vi.fn> };
14
+
15
+ beforeEach(() => {
16
+ // Create SDK with minimal config
17
+ sdk = new TeneoSDK({ wsUrl: "wss://test.teneo.example.com" });
18
+
19
+ // Replace the internal wsClient with a mock that has a writable isConnected
20
+ sendMessageSpy = vi.fn().mockResolvedValue(undefined);
21
+ mockWsClient = {
22
+ isConnected: true,
23
+ sendMessage: sendMessageSpy
24
+ };
25
+ (sdk as any).wsClient = mockWsClient;
26
+ });
27
+
28
+ describe("setApiKeyPreference", () => {
29
+ it("should send correct message shape with useCustomKeys=true", async () => {
30
+ await sdk.setApiKeyPreference(true);
31
+
32
+ expect(sendMessageSpy).toHaveBeenCalledWith({
33
+ type: "set_api_key_preference",
34
+ data: {
35
+ use_custom_keys: true
36
+ }
37
+ });
38
+ });
39
+
40
+ it("should send correct message shape with useCustomKeys=false", async () => {
41
+ await sdk.setApiKeyPreference(false);
42
+
43
+ expect(sendMessageSpy).toHaveBeenCalledWith({
44
+ type: "set_api_key_preference",
45
+ data: {
46
+ use_custom_keys: false
47
+ }
48
+ });
49
+ });
50
+
51
+ it("should throw SDKError when destroyed", async () => {
52
+ (sdk as any).isDestroyed = true;
53
+
54
+ await expect(sdk.setApiKeyPreference(true)).rejects.toThrow("SDK has been destroyed");
55
+
56
+ try {
57
+ await sdk.setApiKeyPreference(true);
58
+ } catch (error: any) {
59
+ expect(error.code).toBe(ErrorCode.SDK_DESTROYED);
60
+ }
61
+ });
62
+
63
+ it("should throw SDKError when not connected", async () => {
64
+ (sdk as any).wsClient.isConnected = false;
65
+
66
+ await expect(sdk.setApiKeyPreference(true)).rejects.toThrow(
67
+ "Not connected to Teneo Protocol"
68
+ );
69
+
70
+ try {
71
+ await sdk.setApiKeyPreference(true);
72
+ } catch (error: any) {
73
+ expect(error.code).toBe(ErrorCode.NOT_CONNECTED);
74
+ }
75
+ });
76
+
77
+ it("should not call sendMessage when destroyed", async () => {
78
+ (sdk as any).isDestroyed = true;
79
+
80
+ try {
81
+ await sdk.setApiKeyPreference(true);
82
+ } catch {
83
+ // Expected
84
+ }
85
+
86
+ expect(sendMessageSpy).not.toHaveBeenCalled();
87
+ });
88
+
89
+ it("should not call sendMessage when not connected", async () => {
90
+ (sdk as any).wsClient.isConnected = false;
91
+
92
+ try {
93
+ await sdk.setApiKeyPreference(false);
94
+ } catch {
95
+ // Expected
96
+ }
97
+
98
+ expect(sendMessageSpy).not.toHaveBeenCalled();
99
+ });
100
+ });
101
+
102
+ describe("sendTxResult", () => {
103
+ it("should send correct message with confirmed status and txHash", async () => {
104
+ await sdk.sendTxResult("task-123", "confirmed", "0xabc123");
105
+
106
+ expect(sendMessageSpy).toHaveBeenCalledWith({
107
+ type: "tx_result",
108
+ data: {
109
+ task_id: "task-123",
110
+ status: "confirmed",
111
+ tx_hash: "0xabc123"
112
+ }
113
+ });
114
+ });
115
+
116
+ it("should send correct message with failed status and error", async () => {
117
+ await sdk.sendTxResult("task-456", "failed", undefined, "Insufficient funds");
118
+
119
+ expect(sendMessageSpy).toHaveBeenCalledWith({
120
+ type: "tx_result",
121
+ data: {
122
+ task_id: "task-456",
123
+ status: "failed",
124
+ error: "Insufficient funds"
125
+ }
126
+ });
127
+ });
128
+
129
+ it("should send correct message with rejected status", async () => {
130
+ await sdk.sendTxResult("task-789", "rejected");
131
+
132
+ expect(sendMessageSpy).toHaveBeenCalledWith({
133
+ type: "tx_result",
134
+ data: {
135
+ task_id: "task-789",
136
+ status: "rejected"
137
+ }
138
+ });
139
+ });
140
+
141
+ it("should not include tx_hash when not provided", async () => {
142
+ await sdk.sendTxResult("task-100", "rejected");
143
+
144
+ const sentMessage = sendMessageSpy.mock.calls[0][0];
145
+ expect(sentMessage.data).not.toHaveProperty("tx_hash");
146
+ });
147
+
148
+ it("should not include error when not provided", async () => {
149
+ await sdk.sendTxResult("task-100", "confirmed", "0xhash");
150
+
151
+ const sentMessage = sendMessageSpy.mock.calls[0][0];
152
+ expect(sentMessage.data).not.toHaveProperty("error");
153
+ });
154
+
155
+ it("should include both tx_hash and error when both provided", async () => {
156
+ await sdk.sendTxResult("task-200", "failed", "0xhash", "Reverted");
157
+
158
+ expect(sendMessageSpy).toHaveBeenCalledWith({
159
+ type: "tx_result",
160
+ data: {
161
+ task_id: "task-200",
162
+ status: "failed",
163
+ tx_hash: "0xhash",
164
+ error: "Reverted"
165
+ }
166
+ });
167
+ });
168
+
169
+ it("should throw SDKError when destroyed", async () => {
170
+ (sdk as any).isDestroyed = true;
171
+
172
+ await expect(sdk.sendTxResult("task-1", "confirmed", "0xhash")).rejects.toThrow(
173
+ "SDK has been destroyed"
174
+ );
175
+
176
+ try {
177
+ await sdk.sendTxResult("task-1", "confirmed", "0xhash");
178
+ } catch (error: any) {
179
+ expect(error.code).toBe(ErrorCode.SDK_DESTROYED);
180
+ }
181
+ });
182
+
183
+ it("should throw SDKError when not connected", async () => {
184
+ (sdk as any).wsClient.isConnected = false;
185
+
186
+ await expect(sdk.sendTxResult("task-1", "confirmed", "0xhash")).rejects.toThrow(
187
+ "Not connected to Teneo Protocol"
188
+ );
189
+
190
+ try {
191
+ await sdk.sendTxResult("task-1", "confirmed", "0xhash");
192
+ } catch (error: any) {
193
+ expect(error.code).toBe(ErrorCode.NOT_CONNECTED);
194
+ }
195
+ });
196
+
197
+ it("should not call sendMessage when destroyed", async () => {
198
+ (sdk as any).isDestroyed = true;
199
+
200
+ try {
201
+ await sdk.sendTxResult("task-1", "confirmed");
202
+ } catch {
203
+ // Expected
204
+ }
205
+
206
+ expect(sendMessageSpy).not.toHaveBeenCalled();
207
+ });
208
+
209
+ it("should not call sendMessage when not connected", async () => {
210
+ (sdk as any).wsClient.isConnected = false;
211
+
212
+ try {
213
+ await sdk.sendTxResult("task-1", "failed", undefined, "err");
214
+ } catch {
215
+ // Expected
216
+ }
217
+
218
+ expect(sendMessageSpy).not.toHaveBeenCalled();
219
+ });
220
+ });
221
+ });