@teneo-protocol/sdk 1.0.1 → 2.2.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 (352) hide show
  1. package/.eslintrc.json +11 -2
  2. package/.github/CODEOWNERS +2 -0
  3. package/.github/ISSUE_TEMPLATE/01-bug.yml +85 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  6. package/.github/workflows/claude-code-review.yml +8 -3
  7. package/.github/workflows/claude-reviewer.yml +6 -4
  8. package/.github/workflows/publish-npm.yml +9 -6
  9. package/.github/workflows/push-to-main.yml +1 -1
  10. package/.github/workflows/top-issue.yml +102 -0
  11. package/CHANGELOG.md +334 -0
  12. package/CONCEPTS.md +747 -0
  13. package/README.md +577 -54
  14. package/dist/constants.js +8 -8
  15. package/dist/constants.js.map +1 -1
  16. package/dist/core/websocket-client.d.ts +25 -1
  17. package/dist/core/websocket-client.d.ts.map +1 -1
  18. package/dist/core/websocket-client.js +74 -15
  19. package/dist/core/websocket-client.js.map +1 -1
  20. package/dist/formatters/response-formatter.js +4 -0
  21. package/dist/formatters/response-formatter.js.map +1 -1
  22. package/dist/handlers/message-handler-registry.js +2 -1
  23. package/dist/handlers/message-handler-registry.js.map +1 -1
  24. package/dist/handlers/message-handlers/agent-details-response-handler.d.ts +1666 -0
  25. package/dist/handlers/message-handlers/agent-details-response-handler.d.ts.map +1 -0
  26. package/dist/handlers/message-handlers/agent-details-response-handler.js +38 -0
  27. package/dist/handlers/message-handlers/agent-details-response-handler.js.map +1 -0
  28. package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts +76 -0
  29. package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts.map +1 -0
  30. package/dist/handlers/message-handlers/agent-room-operation-response-handler.js +67 -0
  31. package/dist/handlers/message-handlers/agent-room-operation-response-handler.js.map +1 -0
  32. package/dist/handlers/message-handlers/agent-selected-handler.d.ts +92 -38
  33. package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
  34. package/dist/handlers/message-handlers/agent-selected-handler.js +2 -5
  35. package/dist/handlers/message-handlers/agent-selected-handler.js.map +1 -1
  36. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +1687 -0
  37. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -0
  38. package/dist/handlers/message-handlers/agent-status-update-handler.js +48 -0
  39. package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -0
  40. package/dist/handlers/message-handlers/agents-list-handler.js +2 -5
  41. package/dist/handlers/message-handlers/agents-list-handler.js.map +1 -1
  42. package/dist/handlers/message-handlers/all-agents-response-handler.d.ts +439 -0
  43. package/dist/handlers/message-handlers/all-agents-response-handler.d.ts.map +1 -0
  44. package/dist/handlers/message-handlers/all-agents-response-handler.js +36 -0
  45. package/dist/handlers/message-handlers/all-agents-response-handler.js.map +1 -0
  46. package/dist/handlers/message-handlers/auth-error-handler.d.ts +45 -31
  47. package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
  48. package/dist/handlers/message-handlers/auth-error-handler.js +2 -5
  49. package/dist/handlers/message-handlers/auth-error-handler.js.map +1 -1
  50. package/dist/handlers/message-handlers/auth-message-handler.d.ts +6 -0
  51. package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
  52. package/dist/handlers/message-handlers/auth-message-handler.js +71 -10
  53. package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
  54. package/dist/handlers/message-handlers/auth-required-handler.d.ts +49 -31
  55. package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
  56. package/dist/handlers/message-handlers/auth-required-handler.js +2 -5
  57. package/dist/handlers/message-handlers/auth-required-handler.js.map +1 -1
  58. package/dist/handlers/message-handlers/auth-success-handler.d.ts +6 -0
  59. package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
  60. package/dist/handlers/message-handlers/auth-success-handler.js +52 -9
  61. package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
  62. package/dist/handlers/message-handlers/base-handler.d.ts +4 -4
  63. package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -1
  64. package/dist/handlers/message-handlers/base-handler.js +3 -1
  65. package/dist/handlers/message-handlers/base-handler.js.map +1 -1
  66. package/dist/handlers/message-handlers/challenge-handler.d.ts +45 -31
  67. package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
  68. package/dist/handlers/message-handlers/challenge-handler.js +3 -2
  69. package/dist/handlers/message-handlers/challenge-handler.js.map +1 -1
  70. package/dist/handlers/message-handlers/error-message-handler.d.ts +49 -31
  71. package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
  72. package/dist/handlers/message-handlers/error-message-handler.js +2 -5
  73. package/dist/handlers/message-handlers/error-message-handler.js.map +1 -1
  74. package/dist/handlers/message-handlers/index.d.ts +11 -0
  75. package/dist/handlers/message-handlers/index.d.ts.map +1 -1
  76. package/dist/handlers/message-handlers/index.js +55 -1
  77. package/dist/handlers/message-handlers/index.js.map +1 -1
  78. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +1660 -0
  79. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -0
  80. package/dist/handlers/message-handlers/list-available-agents-handler.js +35 -0
  81. package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -0
  82. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +1669 -0
  83. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -0
  84. package/dist/handlers/message-handlers/list-room-agents-handler.js +48 -0
  85. package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -0
  86. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +2 -110
  87. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
  88. package/dist/handlers/message-handlers/list-rooms-response-handler.js +4 -6
  89. package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -1
  90. package/dist/handlers/message-handlers/ping-pong-handler.d.ts +62 -58
  91. package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
  92. package/dist/handlers/message-handlers/ping-pong-handler.js +4 -10
  93. package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -1
  94. package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts +94 -0
  95. package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts.map +1 -0
  96. package/dist/handlers/message-handlers/rate-limit-notification-handler.js +35 -0
  97. package/dist/handlers/message-handlers/rate-limit-notification-handler.js.map +1 -0
  98. package/dist/handlers/message-handlers/regular-message-handler.d.ts +31 -29
  99. package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
  100. package/dist/handlers/message-handlers/regular-message-handler.js +4 -6
  101. package/dist/handlers/message-handlers/regular-message-handler.js.map +1 -1
  102. package/dist/handlers/message-handlers/room-operation-response-handler.d.ts +328 -0
  103. package/dist/handlers/message-handlers/room-operation-response-handler.d.ts.map +1 -0
  104. package/dist/handlers/message-handlers/room-operation-response-handler.js +89 -0
  105. package/dist/handlers/message-handlers/room-operation-response-handler.js.map +1 -0
  106. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +53 -31
  107. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
  108. package/dist/handlers/message-handlers/subscribe-response-handler.js +4 -6
  109. package/dist/handlers/message-handlers/subscribe-response-handler.js.map +1 -1
  110. package/dist/handlers/message-handlers/task-quote-handler.d.ts +14 -0
  111. package/dist/handlers/message-handlers/task-quote-handler.d.ts.map +1 -0
  112. package/dist/handlers/message-handlers/task-quote-handler.js +29 -0
  113. package/dist/handlers/message-handlers/task-quote-handler.js.map +1 -0
  114. package/dist/handlers/message-handlers/task-response-handler.js +2 -5
  115. package/dist/handlers/message-handlers/task-response-handler.js.map +1 -1
  116. package/dist/handlers/message-handlers/types.d.ts +21 -7
  117. package/dist/handlers/message-handlers/types.d.ts.map +1 -1
  118. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +53 -31
  119. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
  120. package/dist/handlers/message-handlers/unsubscribe-response-handler.js +4 -6
  121. package/dist/handlers/message-handlers/unsubscribe-response-handler.js.map +1 -1
  122. package/dist/handlers/message-handlers/user-authenticated-handler.d.ts +40 -0
  123. package/dist/handlers/message-handlers/user-authenticated-handler.d.ts.map +1 -0
  124. package/dist/handlers/message-handlers/user-authenticated-handler.js +28 -0
  125. package/dist/handlers/message-handlers/user-authenticated-handler.js.map +1 -0
  126. package/dist/handlers/message-handlers/user-count-handler.d.ts +49 -0
  127. package/dist/handlers/message-handlers/user-count-handler.d.ts.map +1 -0
  128. package/dist/handlers/message-handlers/user-count-handler.js +31 -0
  129. package/dist/handlers/message-handlers/user-count-handler.js.map +1 -0
  130. package/dist/handlers/webhook-handler.d.ts +1 -1
  131. package/dist/handlers/webhook-handler.d.ts.map +1 -1
  132. package/dist/handlers/webhook-handler.js +14 -5
  133. package/dist/handlers/webhook-handler.js.map +1 -1
  134. package/dist/index.d.ts +6 -1
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.js +19 -2
  137. package/dist/index.js.map +1 -1
  138. package/dist/managers/admin-manager.d.ts +116 -0
  139. package/dist/managers/admin-manager.d.ts.map +1 -0
  140. package/dist/managers/admin-manager.js +169 -0
  141. package/dist/managers/admin-manager.js.map +1 -0
  142. package/dist/managers/agent-registry.d.ts +52 -1
  143. package/dist/managers/agent-registry.d.ts.map +1 -1
  144. package/dist/managers/agent-registry.js +145 -6
  145. package/dist/managers/agent-registry.js.map +1 -1
  146. package/dist/managers/agent-room-manager.d.ts +216 -0
  147. package/dist/managers/agent-room-manager.d.ts.map +1 -0
  148. package/dist/managers/agent-room-manager.js +555 -0
  149. package/dist/managers/agent-room-manager.js.map +1 -0
  150. package/dist/managers/connection-manager.js +2 -0
  151. package/dist/managers/connection-manager.js.map +1 -1
  152. package/dist/managers/index.d.ts +4 -1
  153. package/dist/managers/index.d.ts.map +1 -1
  154. package/dist/managers/index.js +7 -1
  155. package/dist/managers/index.js.map +1 -1
  156. package/dist/managers/message-router.d.ts +56 -5
  157. package/dist/managers/message-router.d.ts.map +1 -1
  158. package/dist/managers/message-router.js +155 -8
  159. package/dist/managers/message-router.js.map +1 -1
  160. package/dist/managers/room-management-manager.d.ts +213 -0
  161. package/dist/managers/room-management-manager.d.ts.map +1 -0
  162. package/dist/managers/room-management-manager.js +442 -0
  163. package/dist/managers/room-management-manager.js.map +1 -0
  164. package/dist/managers/room-manager.d.ts +11 -9
  165. package/dist/managers/room-manager.d.ts.map +1 -1
  166. package/dist/managers/room-manager.js +14 -10
  167. package/dist/managers/room-manager.js.map +1 -1
  168. package/dist/payments/index.d.ts +5 -0
  169. package/dist/payments/index.d.ts.map +1 -0
  170. package/dist/payments/index.js +21 -0
  171. package/dist/payments/index.js.map +1 -0
  172. package/dist/payments/payment-client.d.ts +74 -0
  173. package/dist/payments/payment-client.d.ts.map +1 -0
  174. package/dist/payments/payment-client.js +207 -0
  175. package/dist/payments/payment-client.js.map +1 -0
  176. package/dist/teneo-sdk.d.ts +467 -33
  177. package/dist/teneo-sdk.d.ts.map +1 -1
  178. package/dist/teneo-sdk.js +735 -26
  179. package/dist/teneo-sdk.js.map +1 -1
  180. package/dist/types/categories.d.ts +22 -0
  181. package/dist/types/categories.d.ts.map +1 -0
  182. package/dist/types/categories.js +40 -0
  183. package/dist/types/categories.js.map +1 -0
  184. package/dist/types/config.d.ts +134 -54
  185. package/dist/types/config.d.ts.map +1 -1
  186. package/dist/types/config.js +70 -9
  187. package/dist/types/config.js.map +1 -1
  188. package/dist/types/error-codes.d.ts +10 -0
  189. package/dist/types/error-codes.d.ts.map +1 -1
  190. package/dist/types/error-codes.js +12 -0
  191. package/dist/types/error-codes.js.map +1 -1
  192. package/dist/types/events.d.ts +176 -68
  193. package/dist/types/events.d.ts.map +1 -1
  194. package/dist/types/events.js +19 -1
  195. package/dist/types/events.js.map +1 -1
  196. package/dist/types/index.d.ts +3 -2
  197. package/dist/types/index.d.ts.map +1 -1
  198. package/dist/types/index.js +57 -2
  199. package/dist/types/index.js.map +1 -1
  200. package/dist/types/messages.d.ts +22225 -2592
  201. package/dist/types/messages.d.ts.map +1 -1
  202. package/dist/types/messages.js +537 -28
  203. package/dist/types/messages.js.map +1 -1
  204. package/dist/utils/bounded-queue.d.ts.map +1 -1
  205. package/dist/utils/bounded-queue.js +5 -2
  206. package/dist/utils/bounded-queue.js.map +1 -1
  207. package/dist/utils/circuit-breaker.js +11 -4
  208. package/dist/utils/circuit-breaker.js.map +1 -1
  209. package/dist/utils/deduplication-cache.js +3 -1
  210. package/dist/utils/deduplication-cache.js.map +1 -1
  211. package/dist/utils/event-waiter.d.ts +3 -3
  212. package/dist/utils/event-waiter.d.ts.map +1 -1
  213. package/dist/utils/index.d.ts +1 -0
  214. package/dist/utils/index.d.ts.map +1 -1
  215. package/dist/utils/index.js +4 -1
  216. package/dist/utils/index.js.map +1 -1
  217. package/dist/utils/logger.js.map +1 -1
  218. package/dist/utils/pricing-resolver.d.ts +26 -0
  219. package/dist/utils/pricing-resolver.d.ts.map +1 -0
  220. package/dist/utils/pricing-resolver.js +85 -0
  221. package/dist/utils/pricing-resolver.js.map +1 -0
  222. package/dist/utils/rate-limiter.d.ts.map +1 -1
  223. package/dist/utils/rate-limiter.js +6 -0
  224. package/dist/utils/rate-limiter.js.map +1 -1
  225. package/dist/utils/retry-policy.js +1 -0
  226. package/dist/utils/retry-policy.js.map +1 -1
  227. package/dist/utils/secure-private-key.js +3 -1
  228. package/dist/utils/secure-private-key.js.map +1 -1
  229. package/dist/utils/signature-verifier.d.ts.map +1 -1
  230. package/dist/utils/signature-verifier.js +3 -1
  231. package/dist/utils/signature-verifier.js.map +1 -1
  232. package/examples/.env.example +2 -2
  233. package/examples/agent-room-management-example.ts +335 -0
  234. package/examples/basic-usage.ts +3 -4
  235. package/examples/claude-agent-x-follower/.env.example +3 -3
  236. package/examples/claude-agent-x-follower/QUICKSTART.md +3 -3
  237. package/examples/claude-agent-x-follower/README.md +3 -3
  238. package/examples/claude-agent-x-follower/index.ts +120 -96
  239. package/examples/n8n-teneo/.env.example +3 -3
  240. package/examples/n8n-teneo/README.md +2 -2
  241. package/examples/n8n-teneo/index.ts +54 -44
  242. package/examples/nestjs-dashboard/.env.example +11 -0
  243. package/examples/nestjs-dashboard/README.md +297 -0
  244. package/examples/nestjs-dashboard/nest-cli.json +10 -0
  245. package/examples/nestjs-dashboard/package.json +44 -0
  246. package/examples/nestjs-dashboard/pnpm-lock.yaml +3079 -0
  247. package/examples/nestjs-dashboard/src/app.controller.ts +24 -0
  248. package/examples/nestjs-dashboard/src/app.module.ts +15 -0
  249. package/examples/nestjs-dashboard/src/main.ts +32 -0
  250. package/examples/nestjs-dashboard/src/public/dashboard.html +1144 -0
  251. package/examples/nestjs-dashboard/src/teneo/agents.controller.ts +54 -0
  252. package/examples/nestjs-dashboard/src/teneo/events.controller.ts +65 -0
  253. package/examples/nestjs-dashboard/src/teneo/messages.controller.ts +47 -0
  254. package/examples/nestjs-dashboard/src/teneo/rooms.controller.ts +258 -0
  255. package/examples/nestjs-dashboard/src/teneo/teneo.module.ts +13 -0
  256. package/examples/nestjs-dashboard/src/teneo/teneo.service.ts +484 -0
  257. package/examples/nestjs-dashboard/tsconfig.json +22 -0
  258. package/examples/openai-teneo/.env.example +3 -3
  259. package/examples/openai-teneo/README.md +3 -3
  260. package/examples/openai-teneo/index.ts +82 -71
  261. package/examples/production-dashboard/.env.example +3 -3
  262. package/examples/production-dashboard/README.md +90 -13
  263. package/examples/production-dashboard/public/dashboard.html +1173 -601
  264. package/examples/production-dashboard/server.ts +349 -7
  265. package/examples/room-management-example.ts +282 -0
  266. package/examples/usage/.env.example +2 -2
  267. package/examples/usage/01-connect.ts +3 -4
  268. package/examples/usage/02-list-agents.ts +2 -3
  269. package/examples/usage/03-pick-agent.ts +2 -3
  270. package/examples/usage/04-find-by-capability.ts +2 -3
  271. package/examples/usage/05-webhook-example.ts +2 -3
  272. package/examples/usage/06-simple-api-server.ts +2 -3
  273. package/examples/usage/07-event-listener.ts +2 -3
  274. package/examples/usage/README.md +1 -1
  275. package/examples/webhook-integration.ts +1 -1
  276. package/examples/x-influencer-battle-server.ts +2 -2
  277. package/package.json +12 -1
  278. package/src/core/websocket-client.test.ts +8 -3
  279. package/src/core/websocket-client.ts +58 -4
  280. package/src/formatters/response-formatter.test.ts +2 -0
  281. package/src/formatters/response-formatter.ts +3 -3
  282. package/src/handlers/message-handlers/agent-details-response-handler.ts +42 -0
  283. package/src/handlers/message-handlers/agent-room-operation-response-handler.ts +77 -0
  284. package/src/handlers/message-handlers/agent-status-update-handler.ts +52 -0
  285. package/src/handlers/message-handlers/all-agents-response-handler.ts +39 -0
  286. package/src/handlers/message-handlers/auth-message-handler.ts +78 -5
  287. package/src/handlers/message-handlers/auth-success-handler.ts +63 -6
  288. package/src/handlers/message-handlers/base-handler.ts +20 -7
  289. package/src/handlers/message-handlers/index.ts +53 -0
  290. package/src/handlers/message-handlers/list-available-agents-handler.ts +41 -0
  291. package/src/handlers/message-handlers/list-room-agents-handler.ts +58 -0
  292. package/src/handlers/message-handlers/list-rooms-response-handler.ts +4 -2
  293. package/src/handlers/message-handlers/rate-limit-notification-handler.ts +45 -0
  294. package/src/handlers/message-handlers/regular-message-handler.ts +3 -2
  295. package/src/handlers/message-handlers/room-operation-response-handler.ts +102 -0
  296. package/src/handlers/message-handlers/subscribe-response-handler.ts +12 -2
  297. package/src/handlers/message-handlers/task-quote-handler.ts +31 -0
  298. package/src/handlers/message-handlers/types.ts +41 -7
  299. package/src/handlers/message-handlers/unsubscribe-response-handler.ts +12 -2
  300. package/src/handlers/message-handlers/user-authenticated-handler.ts +31 -0
  301. package/src/handlers/message-handlers/user-count-handler.ts +34 -0
  302. package/src/handlers/webhook-handler.test.ts +3 -2
  303. package/src/handlers/webhook-handler.ts +13 -7
  304. package/src/index.ts +21 -0
  305. package/src/managers/admin-manager.ts +249 -0
  306. package/src/managers/agent-registry.test.ts +2 -1
  307. package/src/managers/agent-registry.ts +170 -2
  308. package/src/managers/agent-room-manager.ts +665 -0
  309. package/src/managers/index.ts +15 -1
  310. package/src/managers/message-router.ts +215 -17
  311. package/src/managers/room-management-manager.ts +520 -0
  312. package/src/managers/room-manager.ts +15 -20
  313. package/src/payments/index.ts +22 -0
  314. package/src/payments/payment-client.ts +240 -0
  315. package/src/teneo-sdk.ts +806 -30
  316. package/src/types/categories.ts +45 -0
  317. package/src/types/config.ts +80 -7
  318. package/src/types/error-codes.ts +14 -0
  319. package/src/types/events.test.ts +1 -0
  320. package/src/types/events.ts +67 -0
  321. package/src/types/index.ts +111 -0
  322. package/src/types/messages.test.ts +2 -1
  323. package/src/types/messages.ts +677 -42
  324. package/src/utils/bounded-queue.test.ts +1 -1
  325. package/src/utils/bounded-queue.ts +2 -1
  326. package/src/utils/circuit-breaker.test.ts +1 -1
  327. package/src/utils/deduplication-cache.test.ts +1 -1
  328. package/src/utils/event-waiter.test.ts +1 -1
  329. package/src/utils/event-waiter.ts +3 -3
  330. package/src/utils/index.ts +7 -0
  331. package/src/utils/logger.ts +8 -8
  332. package/src/utils/pricing-resolver.ts +128 -0
  333. package/src/utils/rate-limiter.test.ts +1 -1
  334. package/src/utils/rate-limiter.ts +1 -0
  335. package/src/utils/signature-verifier.test.ts +2 -2
  336. package/src/utils/signature-verifier.ts +3 -2
  337. package/tests/.env.example +7 -0
  338. package/tests/direct-agent-test.ts +151 -0
  339. package/tests/integration/real-server.test.ts +2 -0
  340. package/tests/integration/room-management.test.ts +516 -0
  341. package/tests/integration/websocket.test.ts +5 -2
  342. package/tests/payment-flow-test.ts +147 -0
  343. package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +382 -0
  344. package/tests/unit/handlers/agent-status-update-handler.test.ts +403 -0
  345. package/tests/unit/handlers/auth-success-handler-rooms.test.ts +697 -0
  346. package/tests/unit/handlers/list-available-agents-handler.test.ts +248 -0
  347. package/tests/unit/handlers/list-room-agents-handler.test.ts +290 -0
  348. package/tests/unit/handlers/room-operation-response-handler.test.ts +500 -0
  349. package/tests/unit/managers/agent-room-manager.test.ts +527 -0
  350. package/tests/unit/managers/room-management-manager.test.ts +420 -0
  351. package/tsconfig.json +2 -2
  352. package/vitest.config.ts +1 -0
package/src/teneo-sdk.ts CHANGED
@@ -6,18 +6,19 @@
6
6
 
7
7
  import { EventEmitter } from "eventemitter3";
8
8
  import { z } from "zod";
9
+ import { privateKeyToAccount } from "viem/accounts";
9
10
  import {
10
11
  SDKConfig,
11
12
  PartialSDKConfig,
12
13
  PartialSDKConfigSchema,
13
14
  SDKConfigBuilder,
14
15
  Agent,
15
- Room,
16
16
  RoomInfo,
17
17
  Logger,
18
18
  validateConfig,
19
19
  DEFAULT_CONFIG,
20
20
  ResponseFormatSchema,
21
+ AgentRoomInfo,
21
22
  type HealthStatus
22
23
  } from "./types";
23
24
  import { SDKEvents, SDKError } from "./types/events";
@@ -32,16 +33,29 @@ import {
32
33
  import {
33
34
  ConnectionManager,
34
35
  RoomManager,
36
+ RoomManagementManager,
37
+ AgentRoomManager,
35
38
  AgentRegistry,
36
39
  MessageRouter,
37
40
  SendMessageOptions,
38
- AgentCommand
41
+ AgentCommand,
42
+ QuoteResult,
43
+ AdminManager,
44
+ ListAllAgentsOptions,
45
+ AllAgentsResult
39
46
  } from "./managers";
40
47
  import { createPinoLogger } from "./utils/logger";
41
48
  import { RoomIdSchema, AgentIdSchema, AgentCommandContentSchema } from "./types/validation";
49
+ import { SecurePrivateKey } from "./utils/secure-private-key";
42
50
 
43
51
  // Re-export types for external use
44
- export type { SendMessageOptions, AgentCommand };
52
+ export type {
53
+ SendMessageOptions,
54
+ AgentCommand,
55
+ QuoteResult,
56
+ ListAllAgentsOptions,
57
+ AllAgentsResult
58
+ };
45
59
 
46
60
  // Zod schemas for SDK-specific interfaces
47
61
  export const SendMessageOptionsSchema = z.object({
@@ -62,6 +76,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
62
76
  private config: SDKConfig;
63
77
  private readonly logger: Logger;
64
78
  private isDestroyed = false;
79
+ private secureKey?: SecurePrivateKey;
65
80
 
66
81
  // Core components
67
82
  private readonly wsClient: WebSocketClient;
@@ -71,8 +86,11 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
71
86
  // Managers
72
87
  private readonly connection: ConnectionManager;
73
88
  private readonly rooms: RoomManager;
89
+ private readonly roomManagement: RoomManagementManager;
90
+ private readonly agentRoom: AgentRoomManager;
74
91
  private readonly agents: AgentRegistry;
75
92
  private readonly messages: MessageRouter;
93
+ private readonly _admin: AdminManager;
76
94
 
77
95
  /**
78
96
  * Creates a new instance of the Teneo Protocol SDK.
@@ -138,6 +156,15 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
138
156
  // Initialize logger
139
157
  this.logger = this.config.logger ?? this.createDefaultLogger();
140
158
 
159
+ // Store secure key for payment client
160
+ if (config.privateKey) {
161
+ if (typeof config.privateKey === "object" && "use" in config.privateKey) {
162
+ this.secureKey = config.privateKey;
163
+ } else {
164
+ this.secureKey = new SecurePrivateKey(config.privateKey as string);
165
+ }
166
+ }
167
+
141
168
  // Initialize core components
142
169
  this.wsClient = new WebSocketClient(this.config);
143
170
  this.webhookHandler = new WebhookHandler(this.config, this.logger);
@@ -149,8 +176,16 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
149
176
  // Initialize managers
150
177
  this.connection = new ConnectionManager(this.wsClient, this.logger);
151
178
  this.rooms = new RoomManager(this.wsClient, this.logger);
179
+ this.roomManagement = new RoomManagementManager(this.wsClient, this.logger);
180
+ this.agentRoom = new AgentRoomManager(this.wsClient, this.logger, this.roomManagement);
152
181
  this.wsClient.setRoomManager(this.rooms); // Enable subscription tracking in handlers
182
+ this.wsClient.setRoomManagementManager(this.roomManagement); // Enable room CRUD in handlers (v2.0.0)
183
+ this.wsClient.setAgentRoomManager(this.agentRoom); // Enable agent-room operations in handlers (v2.0.0)
153
184
  this.agents = new AgentRegistry(this.logger);
185
+ this.agents.setWebSocketClient(this.wsClient); // Enable getAgentDetails requests
186
+ this._admin = new AdminManager(this.wsClient, this.logger);
187
+ this.wsClient.setAdminManager(this._admin); // Enable admin handlers
188
+ this.wsClient.setAgentRegistry(this.agents); // Enable agent details handler
154
189
  this.messages = new MessageRouter(
155
190
  this.wsClient,
156
191
  this.webhookHandler,
@@ -158,10 +193,27 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
158
193
  this.logger,
159
194
  {
160
195
  messageTimeout: this.config.messageTimeout,
161
- responseFormat: this.config.responseFormat
196
+ responseFormat: this.config.responseFormat,
197
+ autoApproveQuotes: this.config.autoApproveQuotes,
198
+ maxPricePerRequest: this.config.maxPricePerRequest,
199
+ quoteTimeout: this.config.quoteTimeout,
200
+ wsUrl: this.config.wsUrl,
201
+ paymentNetwork: this.config.paymentNetwork,
202
+ paymentAsset: this.config.paymentAsset
162
203
  }
163
204
  );
164
205
 
206
+ // Set up payment client if private key is configured (v2.2.0)
207
+ if (this.config.privateKey) {
208
+ const secureKey =
209
+ this.config.privateKey instanceof SecurePrivateKey
210
+ ? this.config.privateKey
211
+ : new SecurePrivateKey(this.config.privateKey);
212
+ const walletAddress =
213
+ this.config.walletAddress || this.deriveWalletAddress(this.config.privateKey);
214
+ this.messages.setPaymentClient(secureKey, walletAddress);
215
+ }
216
+
165
217
  // Set up event forwarding
166
218
  this.setupEventForwarding();
167
219
 
@@ -175,7 +227,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
175
227
  }
176
228
 
177
229
  /**
178
- * Establishes a connection to the Teneo network via WebSocket.
230
+ * Establishes a connection to the Teneo Protocol via WebSocket.
179
231
  * Handles authentication automatically and joins any configured auto-join rooms.
180
232
  * Emits 'connection:open', 'auth:success', and 'ready' events on successful connection.
181
233
  *
@@ -188,7 +240,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
188
240
  * ```typescript
189
241
  * const sdk = new TeneoSDK({ wsUrl: 'wss://example.com', privateKey: '0x...' });
190
242
  * await sdk.connect();
191
- * console.log('Connected to Teneo network');
243
+ * console.log('Connected to Teneo Protocol');
192
244
  * ```
193
245
  */
194
246
  public async connect(): Promise<void> {
@@ -197,7 +249,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
197
249
  }
198
250
 
199
251
  try {
200
- this.logger.info("Connecting to Teneo network");
252
+ this.logger.info("Connecting to Teneo Protocol");
201
253
  await this.connection.connect();
202
254
 
203
255
  // Auto-join rooms if configured
@@ -207,26 +259,26 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
207
259
  }
208
260
  }
209
261
 
210
- this.logger.info("Successfully connected to Teneo network");
262
+ this.logger.info("Successfully connected to Teneo Protocol");
211
263
  } catch (error) {
212
- this.logger.error("Failed to connect to Teneo network", error);
264
+ this.logger.error("Failed to connect to Teneo Protocol", error);
213
265
  throw error;
214
266
  }
215
267
  }
216
268
 
217
269
  /**
218
- * Disconnects from the Teneo network and cleans up all active connections.
270
+ * Disconnects from the Teneo Protocol and cleans up all active connections.
219
271
  * Clears all timers, pending messages, and stops automatic reconnection attempts.
220
272
  * Emits 'disconnect' event after disconnection is complete.
221
273
  *
222
274
  * @example
223
275
  * ```typescript
224
276
  * sdk.disconnect();
225
- * console.log('Disconnected from Teneo network');
277
+ * console.log('Disconnected from Teneo Protocol');
226
278
  * ```
227
279
  */
228
280
  public disconnect(): void {
229
- this.logger.info("Disconnecting from Teneo network");
281
+ this.logger.info("Disconnecting from Teneo Protocol");
230
282
  this.connection.disconnect();
231
283
  }
232
284
 
@@ -298,19 +350,49 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
298
350
  }
299
351
 
300
352
  /**
301
- * Subscribes to a specified room in the Teneo network.
302
- * Agents in the room will be able to see and respond to your messages.
353
+ * Requests a quote for a task from the coordinator.
354
+ * The quote includes agent selection, pricing, and expiration.
355
+ * Does NOT auto-approve - use confirmQuote() to execute.
356
+ */
357
+ public async requestQuote(content: string, room: string): Promise<QuoteResult> {
358
+ return this.messages.requestQuote(content, room);
359
+ }
360
+
361
+ /**
362
+ * Confirms a pending quote and executes the task with payment.
363
+ * Attaches x402 payment header if payment client is configured.
364
+ */
365
+ public async confirmQuote(
366
+ taskId: string,
367
+ options?: { waitForResponse?: boolean; timeout?: number }
368
+ ): Promise<FormattedResponse | void> {
369
+ return this.messages.confirmQuote(taskId, options);
370
+ }
371
+
372
+ /**
373
+ * Gets a pending quote by task ID.
374
+ */
375
+ public getPendingQuote(taskId: string): QuoteResult | undefined {
376
+ return this.messages.getPendingQuote(taskId);
377
+ }
378
+
379
+ /**
380
+ * Subscribes to a public room in the Teneo Protocol.
381
+ * This is only needed for public rooms - private rooms are automatically subscribed.
303
382
  * Emits 'room:subscribed' event when successfully subscribed.
304
383
  *
305
- * @param roomId - The ID of the room to subscribe to
384
+ * @param roomId - The ID of the public room to subscribe to
306
385
  * @returns Promise that resolves when the room has been subscribed
307
386
  * @throws {SDKError} If not connected to the network (ErrorCode.NOT_CONNECTED)
308
387
  * @throws {ValidationError} If roomId is empty or invalid
309
388
  *
310
389
  * @example
311
390
  * ```typescript
312
- * await sdk.subscribeToRoom('general');
313
- * console.log('Subscribed to general room');
391
+ * // Subscribe to a public room
392
+ * await sdk.subscribeToRoom('public-announcements');
393
+ * console.log('Subscribed to public room');
394
+ *
395
+ * // Note: Private rooms don't need subscription - you're always subscribed
314
396
  * ```
315
397
  */
316
398
  public async subscribeToRoom(roomId: string): Promise<void> {
@@ -318,19 +400,21 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
318
400
  }
319
401
 
320
402
  /**
321
- * Unsubscribes from a specified room in the Teneo network.
322
- * You will no longer receive messages from agents in this room.
403
+ * Unsubscribes from a public room in the Teneo Protocol.
404
+ * You will no longer receive messages from this public room.
323
405
  * Emits 'room:unsubscribed' event when successfully unsubscribed.
324
406
  *
325
- * @param roomId - The ID of the room to unsubscribe from
407
+ * Note: This only applies to public rooms. Private rooms cannot be unsubscribed from.
408
+ *
409
+ * @param roomId - The ID of the public room to unsubscribe from
326
410
  * @returns Promise that resolves when the room has been unsubscribed
327
411
  * @throws {SDKError} If not connected to the network (ErrorCode.NOT_CONNECTED)
328
412
  * @throws {ValidationError} If roomId is empty or invalid
329
413
  *
330
414
  * @example
331
415
  * ```typescript
332
- * await sdk.unsubscribeFromRoom('general');
333
- * console.log('Unsubscribed from general room');
416
+ * await sdk.unsubscribeFromRoom('public-announcements');
417
+ * console.log('Unsubscribed from public room');
334
418
  * ```
335
419
  */
336
420
  public async unsubscribeFromRoom(roomId: string): Promise<void> {
@@ -376,7 +460,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
376
460
  }
377
461
 
378
462
  /**
379
- * Gets a list of all available agents in the Teneo network.
463
+ * Gets a list of all available agents in the Teneo Protocol.
380
464
  * The list is automatically updated when new agents join or leave.
381
465
  * Returns a read-only array to prevent external modification.
382
466
  *
@@ -486,7 +570,84 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
486
570
  }
487
571
 
488
572
  /**
489
- * Gets a list of all available rooms in the Teneo network.
573
+ * Fetches detailed information about a specific agent from the server.
574
+ * Makes a request to the server for full agent details including capabilities,
575
+ * commands, pricing, and more.
576
+ *
577
+ * @param agentId - The unique identifier of the agent
578
+ * @returns Promise that resolves with full agent details
579
+ * @throws {SDKError} If not connected or request times out
580
+ * @throws {ValidationError} If agentId is invalid
581
+ *
582
+ * @example
583
+ * ```typescript
584
+ * const details = await sdk.getAgentDetails('weather-agent-001');
585
+ * console.log(`Agent: ${details.agent_name}`);
586
+ * console.log(`Capabilities: ${details.capabilities?.length}`);
587
+ * console.log(`Status: ${details.status}`);
588
+ * ```
589
+ */
590
+ public async getAgentDetails(agentId: string): Promise<AgentRoomInfo> {
591
+ return this.agents.getAgentDetails(agentId);
592
+ }
593
+
594
+ // ============================================================================
595
+ // ADMIN API (Admin-Only Features)
596
+ // ============================================================================
597
+
598
+ /**
599
+ * Gets the admin manager for admin-only features.
600
+ * Returns undefined if the current user is not an admin.
601
+ * Use this to access admin APIs like listing all agents, user counts, etc.
602
+ *
603
+ * @returns The AdminManager instance if user is admin, undefined otherwise
604
+ *
605
+ * @example
606
+ * ```typescript
607
+ * if (sdk.admin?.isAdmin) {
608
+ * // List all agents in the network
609
+ * const result = await sdk.admin.listAllAgents({ limit: 20 });
610
+ * console.log(`Found ${result.total} agents`);
611
+ *
612
+ * result.agents.forEach(agent => {
613
+ * console.log(`${agent.agent_name}: verified=${agent.is_verified}, banned=${agent.is_banned}`);
614
+ * });
615
+ *
616
+ * // Get user count
617
+ * const userCount = sdk.admin.getLastUserCount();
618
+ * console.log(`Online users: ${userCount?.count}`);
619
+ *
620
+ * // Listen for user count updates
621
+ * sdk.admin.on('user_count', (data) => {
622
+ * console.log(`User count updated: ${data.count}`);
623
+ * });
624
+ * }
625
+ * ```
626
+ */
627
+ public get admin(): AdminManager | undefined {
628
+ return this._admin.isAdmin ? this._admin : undefined;
629
+ }
630
+
631
+ /**
632
+ * Lists all agents in the network (admin only, convenience method).
633
+ * Returns paginated list of agents with full admin information.
634
+ *
635
+ * @param options - Pagination and filter options
636
+ * @returns Promise that resolves with agents list
637
+ * @throws {SDKError} If not connected or not an admin
638
+ *
639
+ * @example
640
+ * ```typescript
641
+ * const result = await sdk.listAllAgents({ limit: 50, filter: 'weather' });
642
+ * console.log(`Found ${result.total} agents matching 'weather'`);
643
+ * ```
644
+ */
645
+ public async listAllAgents(options: ListAllAgentsOptions = {}): Promise<AllAgentsResult> {
646
+ return this._admin.listAllAgents(options);
647
+ }
648
+
649
+ /**
650
+ * Gets a list of all available rooms in the Teneo Protocol.
490
651
  * Includes rooms you have access to based on your authentication.
491
652
  * Returns a read-only array to prevent external modification.
492
653
  *
@@ -501,7 +662,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
501
662
  * });
502
663
  * ```
503
664
  */
504
- public getRooms(): ReadonlyArray<Room> {
665
+ public getRooms(): ReadonlyArray<RoomInfo> {
505
666
  return this.rooms.getRooms();
506
667
  }
507
668
 
@@ -523,10 +684,464 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
523
684
  * }
524
685
  * ```
525
686
  */
526
- public getRoom(roomId: string): Room | undefined {
687
+ public getRoom(roomId: string): RoomInfo | undefined {
527
688
  return this.rooms.getRoom(roomId);
528
689
  }
529
690
 
691
+ // ============================================================================
692
+ // ROOM MANAGEMENT API (v2.0.0)
693
+ // ============================================================================
694
+
695
+ /**
696
+ * Creates a new private or public room.
697
+ * Checks room limit before creating (for private rooms).
698
+ * Emits 'room:created' event on success, 'room:create_error' on failure.
699
+ *
700
+ * @param options - Room creation options
701
+ * @param options.name - Room name (1-100 characters)
702
+ * @param options.description - Optional room description (max 500 characters)
703
+ * @param options.isPublic - Whether room is public (default: false)
704
+ * @returns Promise that resolves with created room info
705
+ * @throws {SDKError} If not connected, over limit, or validation fails
706
+ *
707
+ * @example
708
+ * ```typescript
709
+ * const room = await sdk.createRoom({
710
+ * name: 'My Project Room',
711
+ * description: 'Collaboration space for my project',
712
+ * isPublic: false
713
+ * });
714
+ * console.log(`Created room: ${room.id}`);
715
+ * ```
716
+ */
717
+ public async createRoom(options: {
718
+ name: string;
719
+ description?: string;
720
+ isPublic?: boolean;
721
+ }): Promise<RoomInfo> {
722
+ return this.roomManagement.createRoom(options);
723
+ }
724
+
725
+ /**
726
+ * Updates an existing room's name and/or description.
727
+ * User must own the room to update it.
728
+ * Emits 'room:updated' event on success, 'room:update_error' on failure.
729
+ *
730
+ * @param roomId - ID of room to update
731
+ * @param updates - Fields to update
732
+ * @param updates.name - New room name (1-100 characters)
733
+ * @param updates.description - New room description (max 500 characters)
734
+ * @returns Promise that resolves with updated room info
735
+ * @throws {SDKError} If not connected, not owner, or validation fails
736
+ *
737
+ * @example
738
+ * ```typescript
739
+ * const room = await sdk.updateRoom('room-123', {
740
+ * name: 'Updated Room Name',
741
+ * description: 'New description'
742
+ * });
743
+ * ```
744
+ */
745
+ public async updateRoom(
746
+ roomId: string,
747
+ updates: { name?: string; description?: string }
748
+ ): Promise<RoomInfo> {
749
+ return this.roomManagement.updateRoom(roomId, updates);
750
+ }
751
+
752
+ /**
753
+ * Deletes a room permanently.
754
+ * User must own the room to delete it.
755
+ * Emits 'room:deleted' event on success, 'room:delete_error' on failure.
756
+ *
757
+ * @param roomId - ID of room to delete
758
+ * @returns Promise that resolves when room is deleted
759
+ * @throws {SDKError} If not connected or not owner
760
+ *
761
+ * @example
762
+ * ```typescript
763
+ * await sdk.deleteRoom('room-123');
764
+ * console.log('Room deleted successfully');
765
+ * ```
766
+ */
767
+ public async deleteRoom(roomId: string): Promise<void> {
768
+ return this.roomManagement.deleteRoom(roomId);
769
+ }
770
+
771
+ /**
772
+ * Gets all rooms owned by the current user.
773
+ * Synchronous method that returns cached data from authentication.
774
+ *
775
+ * @returns Array of owned room info
776
+ *
777
+ * @example
778
+ * ```typescript
779
+ * const myRooms = sdk.getOwnedRooms();
780
+ * console.log(`I own ${myRooms.length} rooms`);
781
+ * myRooms.forEach(room => {
782
+ * console.log(`- ${room.name} (${room.id})`);
783
+ * });
784
+ * ```
785
+ */
786
+ public getOwnedRooms(): ReadonlyArray<Readonly<RoomInfo>> {
787
+ return this.roomManagement.getOwnedRooms();
788
+ }
789
+
790
+ /**
791
+ * Gets all rooms the user is a member of (but doesn't own).
792
+ * Synchronous method that returns cached data from authentication.
793
+ *
794
+ * @returns Array of shared room info
795
+ *
796
+ * @example
797
+ * ```typescript
798
+ * const sharedRooms = sdk.getSharedRooms();
799
+ * console.log(`I'm a member of ${sharedRooms.length} shared rooms`);
800
+ * ```
801
+ */
802
+ public getSharedRooms(): ReadonlyArray<Readonly<RoomInfo>> {
803
+ return this.roomManagement.getSharedRooms();
804
+ }
805
+
806
+ /**
807
+ * Gets all rooms the user has access to (both owned and shared).
808
+ * Convenience method that combines getOwnedRooms() and getSharedRooms().
809
+ * Synchronous method that returns cached data from authentication.
810
+ *
811
+ * @returns Array of all room info (owned + shared)
812
+ *
813
+ * @example
814
+ * ```typescript
815
+ * const allRooms = sdk.getAllRooms();
816
+ * console.log(`I have access to ${allRooms.length} total rooms`);
817
+ *
818
+ * // You can filter by ownership if needed
819
+ * const myRooms = allRooms.filter(r => r.is_owner);
820
+ * const sharedWithMe = allRooms.filter(r => !r.is_owner);
821
+ * ```
822
+ */
823
+ public getAllRooms(): ReadonlyArray<Readonly<RoomInfo>> {
824
+ return this.roomManagement.getAllRooms();
825
+ }
826
+
827
+ /**
828
+ * Gets the maximum number of private rooms the user can create.
829
+ * Based on user's subscription/plan.
830
+ *
831
+ * @returns Maximum private room limit
832
+ *
833
+ * @example
834
+ * ```typescript
835
+ * const limit = sdk.getRoomLimit();
836
+ * const current = sdk.getOwnedRoomCount();
837
+ * console.log(`Using ${current}/${limit} room slots`);
838
+ * ```
839
+ */
840
+ public getRoomLimit(): number {
841
+ return this.roomManagement.getRoomLimit();
842
+ }
843
+
844
+ /**
845
+ * Gets the current count of owned private rooms.
846
+ *
847
+ * @returns Number of rooms user owns
848
+ *
849
+ * @example
850
+ * ```typescript
851
+ * const count = sdk.getOwnedRoomCount();
852
+ * if (sdk.canCreateRoom()) {
853
+ * console.log(`Can create ${sdk.getRoomLimit() - count} more rooms`);
854
+ * }
855
+ * ```
856
+ */
857
+ public getOwnedRoomCount(): number {
858
+ return this.roomManagement.getOwnedRoomCount();
859
+ }
860
+
861
+ /**
862
+ * Checks if user can create another private room.
863
+ * Compares current owned room count against limit.
864
+ *
865
+ * @returns True if under limit, false otherwise
866
+ *
867
+ * @example
868
+ * ```typescript
869
+ * if (sdk.canCreateRoom()) {
870
+ * await sdk.createRoom({ name: 'New Room' });
871
+ * } else {
872
+ * console.log('Room limit reached! Upgrade your plan.');
873
+ * }
874
+ * ```
875
+ */
876
+ public canCreateRoom(): boolean {
877
+ return this.roomManagement.canCreateRoom();
878
+ }
879
+
880
+ // ============================================================================
881
+ // AGENT ROOM MANAGEMENT API (v2.0.0)
882
+ // ============================================================================
883
+
884
+ /**
885
+ * Adds an agent to a room. Only room owners can add agents.
886
+ * Emits 'agent_room:agent_added' on success, 'agent_room:add_error' on failure.
887
+ *
888
+ * @param roomId - ID of the room to add the agent to
889
+ * @param agentId - ID of the agent to add
890
+ * @returns Promise that resolves when agent is added
891
+ * @throws {SDKError} If not connected, not owner, or agent already in room
892
+ *
893
+ * @example
894
+ * ```typescript
895
+ * await sdk.addAgentToRoom('room-123', 'weather-agent');
896
+ * console.log('Agent added to room');
897
+ * ```
898
+ */
899
+ public async addAgentToRoom(roomId: string, agentId: string): Promise<void> {
900
+ return this.agentRoom.addAgentToRoom(roomId, agentId);
901
+ }
902
+
903
+ /**
904
+ * Removes an agent from a room. Only room owners can remove agents.
905
+ * Emits 'agent_room:agent_removed' on success, 'agent_room:remove_error' on failure.
906
+ *
907
+ * @param roomId - ID of the room to remove the agent from
908
+ * @param agentId - ID of the agent to remove
909
+ * @returns Promise that resolves when agent is removed
910
+ * @throws {SDKError} If not connected, not owner, or agent not in room
911
+ *
912
+ * @example
913
+ * ```typescript
914
+ * await sdk.removeAgentFromRoom('room-123', 'weather-agent');
915
+ * console.log('Agent removed from room');
916
+ * ```
917
+ */
918
+ public async removeAgentFromRoom(roomId: string, agentId: string): Promise<void> {
919
+ return this.agentRoom.removeAgentFromRoom(roomId, agentId);
920
+ }
921
+
922
+ /**
923
+ * Lists all agents in a room.
924
+ * Results are cached for 5 minutes for performance.
925
+ * Emits 'agent_room:agents_listed' when list is received.
926
+ *
927
+ * @param roomId - ID of the room to list agents for
928
+ * @param useCache - Whether to use cached data if available (default: true)
929
+ * @returns Promise that resolves to array of agents in the room
930
+ * @throws {SDKError} If not connected
931
+ *
932
+ * @example
933
+ * ```typescript
934
+ * const agents = await sdk.listRoomAgents('room-123');
935
+ * console.log(`Room has ${agents.length} agents`);
936
+ * agents.forEach(agent => {
937
+ * console.log(`- ${agent.agent_name} (${agent.status})`);
938
+ * });
939
+ * ```
940
+ */
941
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
942
+ public async listRoomAgents(roomId: string, useCache: boolean = true): Promise<any[]> {
943
+ return this.agentRoom.listRoomAgents(roomId, useCache);
944
+ }
945
+
946
+ /**
947
+ * Lists all agents available to be added to a room.
948
+ * Shows agents not currently in the room.
949
+ * Results are cached for 5 minutes for performance.
950
+ * Emits 'agent_room:available_agents_listed' when list is received.
951
+ *
952
+ * @param roomId - ID of the room to check available agents for
953
+ * @param useCache - Whether to use cached data if available (default: true)
954
+ * @returns Promise that resolves to array of available agents
955
+ * @throws {SDKError} If not connected
956
+ *
957
+ * @example
958
+ * ```typescript
959
+ * const available = await sdk.listAvailableAgents('room-123');
960
+ * console.log(`${available.length} agents available to add`);
961
+ * ```
962
+ */
963
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
964
+ public async listAvailableAgents(roomId: string, useCache: boolean = true): Promise<any[]> {
965
+ return this.agentRoom.listAvailableAgents(roomId, useCache);
966
+ }
967
+
968
+ /**
969
+ * Gets agents in a room from cache (synchronous).
970
+ * Returns undefined if not cached. Use listRoomAgents() to fetch.
971
+ *
972
+ * @param roomId - ID of the room
973
+ * @returns Array of agents if cached, undefined otherwise
974
+ *
975
+ * @example
976
+ * ```typescript
977
+ * const agents = sdk.getRoomAgents('room-123');
978
+ * if (agents) {
979
+ * console.log(`${agents.length} agents (cached)`);
980
+ * } else {
981
+ * await sdk.listRoomAgents('room-123'); // Fetch from server
982
+ * }
983
+ * ```
984
+ */
985
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
986
+ public getRoomAgents(roomId: string): any[] | undefined {
987
+ return this.agentRoom.getRoomAgents(roomId);
988
+ }
989
+
990
+ /**
991
+ * Gets available agents for a room from cache (synchronous).
992
+ * Returns undefined if not cached. Use listAvailableAgents() to fetch.
993
+ *
994
+ * @param roomId - ID of the room
995
+ * @returns Array of available agents if cached, undefined otherwise
996
+ *
997
+ * @example
998
+ * ```typescript
999
+ * const available = sdk.getAvailableAgents('room-123');
1000
+ * if (available) {
1001
+ * console.log(`${available.length} agents available (cached)`);
1002
+ * }
1003
+ * ```
1004
+ */
1005
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1006
+ public getAvailableAgents(roomId: string): any[] | undefined {
1007
+ return this.agentRoom.getAvailableAgents(roomId);
1008
+ }
1009
+
1010
+ /**
1011
+ * Checks if an agent is in a room (synchronous, from cache).
1012
+ * Returns undefined if room data not cached.
1013
+ *
1014
+ * @param roomId - ID of the room
1015
+ * @param agentId - ID of the agent
1016
+ * @returns True if agent is in room, false if not, undefined if not cached
1017
+ *
1018
+ * @example
1019
+ * ```typescript
1020
+ * const inRoom = sdk.isAgentInRoom('room-123', 'weather-agent');
1021
+ * if (inRoom === true) {
1022
+ * console.log('Agent is in room');
1023
+ * } else if (inRoom === false) {
1024
+ * console.log('Agent is not in room');
1025
+ * } else {
1026
+ * console.log('Room data not cached');
1027
+ * }
1028
+ * ```
1029
+ */
1030
+ public isAgentInRoom(roomId: string, agentId: string): boolean | undefined {
1031
+ return this.agentRoom.isAgentInRoom(roomId, agentId);
1032
+ }
1033
+
1034
+ /**
1035
+ * Gets the count of agents in a room (synchronous, from cache).
1036
+ * Returns undefined if room data not cached.
1037
+ *
1038
+ * @param roomId - ID of the room
1039
+ * @returns Number of agents in room, or undefined if not cached
1040
+ *
1041
+ * @example
1042
+ * ```typescript
1043
+ * const count = sdk.getRoomAgentCount('room-123');
1044
+ * if (count !== undefined) {
1045
+ * console.log(`Room has ${count} agents`);
1046
+ * }
1047
+ * ```
1048
+ */
1049
+ public getRoomAgentCount(roomId: string): number | undefined {
1050
+ return this.agentRoom.getRoomAgentCount(roomId);
1051
+ }
1052
+
1053
+ /**
1054
+ * Invalidates the agent-room cache for a specific room.
1055
+ * Forces the next listRoomAgents() or listAvailableAgents() call to fetch fresh data.
1056
+ * Useful after bulk operations or when you know the cache is stale.
1057
+ *
1058
+ * @param roomId - ID of the room to invalidate cache for
1059
+ *
1060
+ * @example
1061
+ * ```typescript
1062
+ * // After adding/removing agents
1063
+ * await sdk.addAgentToRoom('room-123', 'agent-456');
1064
+ * sdk.invalidateAgentRoomCache('room-123');
1065
+ * const freshAgents = await sdk.listRoomAgents('room-123');
1066
+ * ```
1067
+ */
1068
+ public invalidateAgentRoomCache(roomId: string): void {
1069
+ this.agentRoom.invalidateCache(roomId);
1070
+ }
1071
+
1072
+ /**
1073
+ * Updates user preferences on the server.
1074
+ * Server-side enforcement of max price per request - prevents quotes/payments exceeding the limit.
1075
+ *
1076
+ * @param preferences - User preferences to update
1077
+ * @param preferences.maxPricePerRequest - Max price per request in USDC (e.g., 0.01 = $0.01), or null to remove limit
1078
+ * @returns Promise that resolves when preferences are updated
1079
+ * @throws {SDKError} If update fails or times out
1080
+ *
1081
+ * @example
1082
+ * ```typescript
1083
+ * // Set a spending limit of $0.05 per request
1084
+ * await sdk.setUserPreferences({ maxPricePerRequest: 0.05 });
1085
+ *
1086
+ * // Remove the spending limit
1087
+ * await sdk.setUserPreferences({ maxPricePerRequest: null });
1088
+ * ```
1089
+ */
1090
+ public async setUserPreferences(preferences: {
1091
+ maxPricePerRequest?: number | null;
1092
+ }): Promise<void> {
1093
+ if (this.isDestroyed) {
1094
+ throw new SDKError("SDK has been destroyed", ErrorCode.SDK_DESTROYED, null, false);
1095
+ }
1096
+
1097
+ const message = {
1098
+ type: "set_user_preferences" as const,
1099
+ data: {
1100
+ max_price_per_request: preferences.maxPricePerRequest
1101
+ }
1102
+ };
1103
+
1104
+ return new Promise((resolve, reject) => {
1105
+ const timeout = setTimeout(() => {
1106
+ cleanup();
1107
+ reject(new SDKError("Set user preferences request timed out", ErrorCode.TIMEOUT_ERROR));
1108
+ }, 30000);
1109
+
1110
+ const handleResponse = (msg: {
1111
+ type: string;
1112
+ data?: { success?: boolean; message?: string; max_price_per_request?: number | null };
1113
+ }) => {
1114
+ if (msg.type === "user_preferences_updated") {
1115
+ cleanup();
1116
+ if (msg.data?.success) {
1117
+ this.emit("preferences:updated", {
1118
+ maxPricePerRequest: msg.data.max_price_per_request
1119
+ });
1120
+ resolve();
1121
+ } else {
1122
+ reject(
1123
+ new SDKError(
1124
+ msg.data?.message || "Failed to update preferences",
1125
+ ErrorCode.MESSAGE_ERROR
1126
+ )
1127
+ );
1128
+ }
1129
+ }
1130
+ };
1131
+
1132
+ const cleanup = () => {
1133
+ clearTimeout(timeout);
1134
+ this.wsClient.off("message:received", handleResponse);
1135
+ };
1136
+
1137
+ this.wsClient.on("message:received", handleResponse);
1138
+ this.wsClient.sendMessage(message).catch((error) => {
1139
+ cleanup();
1140
+ reject(error);
1141
+ });
1142
+ });
1143
+ }
1144
+
530
1145
  /**
531
1146
  * Configures webhook URL and headers for receiving real-time event notifications.
532
1147
  * Webhooks allow you to receive events at your server endpoint via HTTP POST requests.
@@ -616,7 +1231,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
616
1231
  * This is a convenience getter that returns only the connection status.
617
1232
  * For detailed state information, use getConnectionState().
618
1233
  *
619
- * @returns True if connected to the Teneo network, false otherwise
1234
+ * @returns True if connected to the Teneo Protocol, false otherwise
620
1235
  *
621
1236
  * @example
622
1237
  * ```typescript
@@ -637,7 +1252,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
637
1252
  * This is a convenience getter that returns only the authentication status.
638
1253
  * For detailed auth information, use getAuthState().
639
1254
  *
640
- * @returns True if authenticated with the Teneo network, false otherwise
1255
+ * @returns True if authenticated with the Teneo Protocol, false otherwise
641
1256
  *
642
1257
  * @example
643
1258
  * ```typescript
@@ -922,6 +1537,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
922
1537
  this.rooms.destroy();
923
1538
  this.agents.destroy();
924
1539
  this.messages.destroy();
1540
+ this._admin.destroy();
925
1541
 
926
1542
  // Destroy other components
927
1543
  this.webhookHandler.destroy();
@@ -951,7 +1567,9 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
951
1567
  this.connection.on("auth:success", (state) => {
952
1568
  this.logger.debug("Received auth:success event in SDK", {
953
1569
  authenticated: state?.authenticated,
954
- hasRooms: !!state?.roomObjects
1570
+ hasRooms: !!state?.roomObjects,
1571
+ ownedRooms: state?.privateRoomIds?.length || 0,
1572
+ sharedRooms: state?.sharedRoomIds?.length || 0
955
1573
  });
956
1574
 
957
1575
  // Update rooms from auth state
@@ -959,6 +1577,23 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
959
1577
  this.rooms.updateRoomsFromAuth(state.roomObjects);
960
1578
  }
961
1579
 
1580
+ // Ensure RoomManagementManager is synced with auth state
1581
+ if (state.roomObjects && state.roomObjects.length > 0) {
1582
+ const ownedRooms = state.roomObjects.filter((r) => r.is_owner);
1583
+ const sharedRooms = state.roomObjects.filter((r) => !r.is_owner);
1584
+ this.roomManagement.setOwnedRooms(ownedRooms);
1585
+ this.roomManagement.setSharedRooms(sharedRooms);
1586
+
1587
+ if (state.maxPrivateRooms) {
1588
+ this.roomManagement.setRoomLimit(state.maxPrivateRooms);
1589
+ }
1590
+ }
1591
+
1592
+ // Set up payment client for x402 payments
1593
+ if (this.secureKey && state.walletAddress) {
1594
+ this.messages.setPaymentClient(this.secureKey, state.walletAddress);
1595
+ }
1596
+
962
1597
  this.emit("auth:success", state);
963
1598
  });
964
1599
  this.connection.on("auth:error", (error) => this.emit("auth:error", error));
@@ -975,6 +1610,12 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
975
1610
  this.messages.on("agent:selected", (data) => this.emit("agent:selected", data));
976
1611
  this.messages.on("agent:response", (response) => this.emit("agent:response", response));
977
1612
 
1613
+ // Forward quote and payment events from MessageRouter (v2.2.0)
1614
+ this.messages.on("quote:received", (quote) => this.emit("quote:received", quote));
1615
+ this.messages.on("payment:blocked", (data) => this.emit("payment:blocked", data));
1616
+ this.messages.on("payment:attached", (data) => this.emit("payment:attached", data));
1617
+ this.messages.on("payment:error", (error) => this.emit("payment:error", error));
1618
+
978
1619
  // Forward coordinator events from MessageRouter
979
1620
  this.messages.on("coordinator:processing", (request) =>
980
1621
  this.emit("coordinator:processing", request)
@@ -993,6 +1634,126 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
993
1634
  this.wsClient.on("room:subscribed", (data) => this.emit("room:subscribed", data));
994
1635
  this.wsClient.on("room:unsubscribed", (data) => this.emit("room:unsubscribed", data));
995
1636
 
1637
+ // Forward room management events from WebSocketClient (emitted by handlers) (v2.0.0)
1638
+ // These events are emitted by message handlers, so we listen on wsClient
1639
+ // We forward to RoomManagementManager first (for promise resolution), then emit on SDK
1640
+ this.wsClient.on("room:created", (room) => {
1641
+ // Update RoomManagementManager cache
1642
+ this.roomManagement.upsertRoom(room);
1643
+ // Emit on RoomManagementManager for promise resolution (see createRoom method)
1644
+ this.roomManagement.emit("room:created", room);
1645
+ // Emit on SDK for external listeners
1646
+ this.emit("room:created", room);
1647
+ });
1648
+ this.wsClient.on("room:updated", (room) => {
1649
+ // Update RoomManagementManager cache
1650
+ this.roomManagement.upsertRoom(room);
1651
+ // Emit on RoomManagementManager for promise resolution (see updateRoom method)
1652
+ this.roomManagement.emit("room:updated", room);
1653
+ // Emit on SDK for external listeners
1654
+ this.emit("room:updated", room);
1655
+ });
1656
+ this.wsClient.on("room:deleted", (roomId) => {
1657
+ // Remove from RoomManagementManager cache
1658
+ this.roomManagement.removeRoom(roomId);
1659
+ // Emit on RoomManagementManager for promise resolution (see deleteRoom method)
1660
+ this.roomManagement.emit("room:deleted", roomId);
1661
+ // Emit on SDK for external listeners
1662
+ this.emit("room:deleted", roomId);
1663
+ });
1664
+ this.wsClient.on("room:create_error", (error) => {
1665
+ // Emit on RoomManagementManager for promise rejection
1666
+ this.roomManagement.emit("room:create_error", error);
1667
+ // Emit on SDK for external listeners
1668
+ this.emit("room:create_error", error);
1669
+ });
1670
+ this.wsClient.on("room:update_error", (error, roomId) => {
1671
+ // Emit on RoomManagementManager for promise rejection
1672
+ this.roomManagement.emit("room:update_error", error, roomId);
1673
+ // Emit on SDK for external listeners
1674
+ this.emit("room:update_error", error, roomId);
1675
+ });
1676
+ this.wsClient.on("room:delete_error", (error, roomId) => {
1677
+ // Emit on RoomManagementManager for promise rejection
1678
+ this.roomManagement.emit("room:delete_error", error, roomId);
1679
+ // Emit on SDK for external listeners
1680
+ this.emit("room:delete_error", error, roomId);
1681
+ });
1682
+
1683
+ // Forward agent room management events from WebSocketClient (emitted by handlers) (v2.0.0)
1684
+ // These events are emitted by message handlers, so we listen on wsClient
1685
+ // We forward to AgentRoomManager first (for promise resolution), then emit on SDK
1686
+ this.wsClient.on("agent_room:agent_added", (roomId, agentId) => {
1687
+ // Emit on AgentRoomManager for promise resolution (see addAgentToRoom method)
1688
+ this.agentRoom.emit("agent_room:agent_added", roomId, agentId);
1689
+ // Emit on SDK for external listeners
1690
+ this.emit("agent_room:agent_added", roomId, agentId);
1691
+ });
1692
+ this.wsClient.on("agent_room:agent_removed", (roomId, agentId) => {
1693
+ // Emit on AgentRoomManager for promise resolution (see removeAgentFromRoom method)
1694
+ this.agentRoom.emit("agent_room:agent_removed", roomId, agentId);
1695
+ // Emit on SDK for external listeners
1696
+ this.emit("agent_room:agent_removed", roomId, agentId);
1697
+ });
1698
+ this.wsClient.on("agent_room:agents_listed", (roomId, agents) => {
1699
+ // Emit on AgentRoomManager for promise resolution
1700
+ this.agentRoom.emit("agent_room:agents_listed", roomId, agents);
1701
+ // Emit on SDK for external listeners
1702
+ this.emit("agent_room:agents_listed", roomId, agents);
1703
+ });
1704
+ this.wsClient.on("agent_room:available_agents_listed", (agents) => {
1705
+ // Emit on AgentRoomManager for promise resolution
1706
+ this.agentRoom.emit("agent_room:available_agents_listed", agents);
1707
+ // Emit on SDK for external listeners
1708
+ this.emit("agent_room:available_agents_listed", agents);
1709
+ });
1710
+ this.wsClient.on("agent_room:status_update", (data) => {
1711
+ // Emit on SDK for external listeners
1712
+ this.emit("agent_room:status_update", data);
1713
+ });
1714
+ this.wsClient.on("agent_room:add_error", (error, roomId) => {
1715
+ // Emit on AgentRoomManager for promise rejection
1716
+ this.agentRoom.emit("agent_room:add_error", error, roomId);
1717
+ // Emit on SDK for external listeners
1718
+ this.emit("agent_room:add_error", error, roomId);
1719
+ });
1720
+ this.wsClient.on("agent_room:remove_error", (error, roomId) => {
1721
+ // Emit on AgentRoomManager for promise rejection
1722
+ this.agentRoom.emit("agent_room:remove_error", error, roomId);
1723
+ // Emit on SDK for external listeners
1724
+ this.emit("agent_room:remove_error", error, roomId);
1725
+ });
1726
+ this.wsClient.on("agent_room:list_error", (error, roomId) => {
1727
+ // Emit on AgentRoomManager for promise rejection
1728
+ this.agentRoom.emit("agent_room:list_error", error, roomId);
1729
+ // Emit on SDK for external listeners
1730
+ this.emit("agent_room:list_error", error, roomId);
1731
+ });
1732
+ this.wsClient.on("agent_room:list_available_error", (error) => {
1733
+ // Emit on AgentRoomManager for promise rejection
1734
+ this.agentRoom.emit("agent_room:list_available_error", error);
1735
+ // Emit on SDK for external listeners
1736
+ this.emit("agent_room:list_available_error", error);
1737
+ });
1738
+
1739
+ // Forward admin events from AdminManager
1740
+ this._admin.on("user_count", (data) => {
1741
+ this.emit("admin:user_count", data);
1742
+ });
1743
+ this._admin.on("status_changed", (isAdmin) => {
1744
+ this.emit("admin:status_changed", isAdmin);
1745
+ });
1746
+
1747
+ // Forward rate limit notifications from WebSocketClient (emitted by handlers)
1748
+ this.wsClient.on("rate_limit", (notification) => {
1749
+ this.emit("rate_limit", notification);
1750
+ });
1751
+
1752
+ // Forward user authenticated events from WebSocketClient (emitted by handlers)
1753
+ this.wsClient.on("user:authenticated", (data) => {
1754
+ this.emit("user:authenticated", data);
1755
+ });
1756
+
996
1757
  // Forward webhook events from WebhookHandler
997
1758
  this.webhookHandler.on("webhook:sent", (payload, url) =>
998
1759
  this.emit("webhook:sent", payload, url)
@@ -1009,8 +1770,13 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
1009
1770
  this.connection.on("error", (error) => {
1010
1771
  this.emit("error", error);
1011
1772
  // Fire and forget - don't block event emission
1773
+ // Defensive check: ensure error has toJSON method (SDKError instances do)
1774
+ const errorPayload =
1775
+ typeof error.toJSON === "function"
1776
+ ? error.toJSON()
1777
+ : { message: error.message, name: error.name, code: error.code };
1012
1778
  this.webhookHandler
1013
- .sendWebhook("error", error, { code: error.code })
1779
+ .sendWebhook("error", errorPayload, { code: error.code })
1014
1780
  .catch((webhookError) => {
1015
1781
  this.logger.error("Failed to send webhook for error event", webhookError);
1016
1782
  });
@@ -1028,6 +1794,16 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
1028
1794
  return createPinoLogger(this.config.logLevel ?? "info", "TeneoSDK");
1029
1795
  }
1030
1796
 
1797
+ /**
1798
+ * Derive wallet address from private key
1799
+ */
1800
+ private deriveWalletAddress(privateKey: string | SecurePrivateKey): string {
1801
+ if (privateKey instanceof SecurePrivateKey) {
1802
+ return privateKey.use((key) => privateKeyToAccount(key as `0x${string}`).address);
1803
+ }
1804
+ return privateKeyToAccount(privateKey as `0x${string}`).address;
1805
+ }
1806
+
1031
1807
  /**
1032
1808
  * Creates a new SDK configuration builder for fluent configuration.
1033
1809
  * The builder pattern provides a more intuitive way to configure the SDK