@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
@@ -0,0 +1,516 @@
1
+ /**
2
+ * Integration tests for Room Management (v2.0.0)
3
+ * Tests complete room CRUD flow with mock WebSocket server
4
+ */
5
+
6
+ import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "vitest";
7
+ import { WebSocketServer } from "ws";
8
+ import { TeneoSDK } from "../../src";
9
+ import { SDKConfigBuilder } from "../../src/types";
10
+ import { privateKeyToAccount } from "viem/accounts";
11
+ import { generatePrivateKey } from "viem/accounts";
12
+ import { RoomInfo } from "../../src/types";
13
+
14
+ // TODO: Fix integration test setup - mock server needs proper event handling
15
+ describe.skip("Room Management Integration Tests", () => {
16
+ let server: WebSocketServer;
17
+ let sdk: TeneoSDK;
18
+ let serverPort: number;
19
+ let privateKey: string;
20
+ let walletAddress: string;
21
+
22
+ // Mock server to simulate Teneo WebSocket server
23
+ beforeAll(() => {
24
+ serverPort = 8082;
25
+ privateKey = generatePrivateKey();
26
+ const account = privateKeyToAccount(privateKey);
27
+ walletAddress = account.address;
28
+
29
+ // Create WebSocket server
30
+ server = new WebSocketServer({ port: serverPort });
31
+
32
+ // Room storage for testing
33
+ const rooms = new Map<string, RoomInfo>();
34
+ let roomCounter = 1;
35
+
36
+ server.on("connection", (ws) => {
37
+ ws.on("message", (data) => {
38
+ const message = JSON.parse(data.toString());
39
+
40
+ // Handle different message types
41
+ switch (message.type) {
42
+ case "request_challenge":
43
+ ws.send(
44
+ JSON.stringify({
45
+ type: "challenge",
46
+ data: {
47
+ challenge: "test-challenge-" + Date.now(),
48
+ timestamp: Date.now()
49
+ }
50
+ })
51
+ );
52
+ break;
53
+
54
+ case "auth":
55
+ // Send auth success with room management info
56
+ ws.send(
57
+ JSON.stringify({
58
+ type: "auth_success",
59
+ data: {
60
+ id: "client-123",
61
+ type: "user",
62
+ address: message.data.address,
63
+ nft_verified: false,
64
+ is_whitelisted: true,
65
+ rooms: Array.from(rooms.values()),
66
+ max_private_rooms: 5 // v2.0: Room limit
67
+ }
68
+ })
69
+ );
70
+ break;
71
+
72
+ case "create_room": {
73
+ // Create new room
74
+ const newRoomId = `room-${roomCounter++}`;
75
+ const newRoom: RoomInfo = {
76
+ id: newRoomId,
77
+ name: message.name,
78
+ description: message.description,
79
+ is_public: message.is_public || false,
80
+ created_by: walletAddress,
81
+ created_at: new Date().toISOString(),
82
+ updated_at: new Date().toISOString(),
83
+ is_owner: true
84
+ };
85
+ rooms.set(newRoomId, newRoom);
86
+
87
+ // Send success response
88
+ ws.send(
89
+ JSON.stringify({
90
+ type: "room_operation_response",
91
+ data: {
92
+ success: true,
93
+ room: newRoom,
94
+ message: "Room created successfully"
95
+ }
96
+ })
97
+ );
98
+ break;
99
+ }
100
+
101
+ case "update_room": {
102
+ // Update existing room
103
+ const roomId = message.room_id;
104
+ const existingRoom = rooms.get(roomId);
105
+
106
+ if (!existingRoom) {
107
+ ws.send(
108
+ JSON.stringify({
109
+ type: "room_operation_response",
110
+ data: {
111
+ success: false,
112
+ message: "Room not found",
113
+ room_id: roomId
114
+ }
115
+ })
116
+ );
117
+ return;
118
+ }
119
+
120
+ // Update room
121
+ const updatedRoom: RoomInfo = {
122
+ ...existingRoom,
123
+ name: message.name ?? existingRoom.name,
124
+ description: message.description ?? existingRoom.description,
125
+ updated_at: new Date().toISOString()
126
+ };
127
+ rooms.set(roomId, updatedRoom);
128
+
129
+ // Send success response
130
+ ws.send(
131
+ JSON.stringify({
132
+ type: "room_operation_response",
133
+ data: {
134
+ success: true,
135
+ room: updatedRoom,
136
+ message: "Room updated successfully"
137
+ }
138
+ })
139
+ );
140
+ break;
141
+ }
142
+
143
+ case "delete_room": {
144
+ // Delete room
145
+ const deleteRoomId = message.room_id;
146
+ const roomToDelete = rooms.get(deleteRoomId);
147
+
148
+ if (!roomToDelete) {
149
+ ws.send(
150
+ JSON.stringify({
151
+ type: "room_operation_response",
152
+ data: {
153
+ success: false,
154
+ message: "Room not found",
155
+ room_id: deleteRoomId
156
+ }
157
+ })
158
+ );
159
+ return;
160
+ }
161
+
162
+ rooms.delete(deleteRoomId);
163
+
164
+ // Send success response
165
+ ws.send(
166
+ JSON.stringify({
167
+ type: "room_operation_response",
168
+ data: {
169
+ success: true,
170
+ room_id: deleteRoomId,
171
+ message: "Room deleted successfully"
172
+ }
173
+ })
174
+ );
175
+ break;
176
+ }
177
+
178
+ case "ping":
179
+ ws.send(JSON.stringify({ type: "pong" }));
180
+ break;
181
+ }
182
+ });
183
+ });
184
+ });
185
+
186
+ afterAll(() => {
187
+ server.close();
188
+ });
189
+
190
+ beforeEach(async () => {
191
+ // Create SDK instance
192
+ const config = new SDKConfigBuilder()
193
+ .withWebSocketUrl(`ws://localhost:${serverPort}`)
194
+ .withAuthentication(privateKey)
195
+ .withReconnection(false) // Disable for tests
196
+ .build();
197
+
198
+ sdk = new TeneoSDK(config);
199
+
200
+ // Wait for connection and auth
201
+ await new Promise<void>((resolve, reject) => {
202
+ const timeout = setTimeout(() => {
203
+ reject(new Error("Connection timeout"));
204
+ }, 5000);
205
+
206
+ sdk.once("ready", () => {
207
+ clearTimeout(timeout);
208
+ resolve();
209
+ });
210
+
211
+ sdk.once("error", (error) => {
212
+ clearTimeout(timeout);
213
+ reject(error);
214
+ });
215
+
216
+ // Connect to server
217
+ sdk.connect().catch(reject);
218
+ });
219
+ });
220
+
221
+ afterEach(async () => {
222
+ if (sdk) {
223
+ await sdk.destroy();
224
+ }
225
+ });
226
+
227
+ describe("Room Creation", () => {
228
+ it("should create a private room", async () => {
229
+ const roomOptions = {
230
+ name: "Test Private Room",
231
+ description: "A test private room"
232
+ };
233
+
234
+ const room = await sdk.createRoom(roomOptions);
235
+
236
+ expect(room).toBeDefined();
237
+ expect(room.id).toBeDefined();
238
+ expect(room.name).toBe(roomOptions.name);
239
+ expect(room.description).toBe(roomOptions.description);
240
+ expect(room.is_public).toBe(false);
241
+ expect(room.is_owner).toBe(true);
242
+ expect(room.created_by).toBeDefined();
243
+ expect(room.created_at).toBeDefined();
244
+
245
+ // Should be in owned rooms
246
+ const ownedRooms = sdk.getOwnedRooms();
247
+ expect(ownedRooms).toHaveLength(1);
248
+ expect(ownedRooms[0].id).toBe(room.id);
249
+ });
250
+
251
+ it("should emit room:created event", async () => {
252
+ const roomOptions = {
253
+ name: "Event Test Room"
254
+ };
255
+
256
+ const eventPromise = new Promise<RoomInfo>((resolve) => {
257
+ sdk.once("room:created", (room) => {
258
+ resolve(room);
259
+ });
260
+ });
261
+
262
+ const room = await sdk.createRoom(roomOptions);
263
+ const emittedRoom = await eventPromise;
264
+
265
+ expect(emittedRoom.id).toBe(room.id);
266
+ expect(emittedRoom.name).toBe(room.name);
267
+ });
268
+
269
+ it("should validate room name", async () => {
270
+ await expect(sdk.createRoom({ name: "" })).rejects.toThrow("Room name cannot be empty");
271
+
272
+ await expect(sdk.createRoom({ name: "a".repeat(101) })).rejects.toThrow("Room name too long");
273
+ });
274
+
275
+ it("should validate room description", async () => {
276
+ await expect(
277
+ sdk.createRoom({
278
+ name: "Test",
279
+ description: "a".repeat(501)
280
+ })
281
+ ).rejects.toThrow("Room description too long");
282
+ });
283
+ });
284
+
285
+ describe("Room Updates", () => {
286
+ it("should update room name", async () => {
287
+ // Create room first
288
+ const room = await sdk.createRoom({ name: "Original Name" });
289
+
290
+ // Update name
291
+ const updatedRoom = await sdk.updateRoom(room.id, { name: "Updated Name" });
292
+
293
+ expect(updatedRoom.id).toBe(room.id);
294
+ expect(updatedRoom.name).toBe("Updated Name");
295
+
296
+ // Should be updated in cache
297
+ const cachedRoom = sdk.getRoomById(room.id);
298
+ expect(cachedRoom?.name).toBe("Updated Name");
299
+ });
300
+
301
+ it("should update room description", async () => {
302
+ const room = await sdk.createRoom({ name: "Test Room" });
303
+
304
+ const updatedRoom = await sdk.updateRoom(room.id, {
305
+ description: "New description"
306
+ });
307
+
308
+ expect(updatedRoom.description).toBe("New description");
309
+ });
310
+
311
+ it("should update both name and description", async () => {
312
+ const room = await sdk.createRoom({ name: "Test Room" });
313
+
314
+ const updatedRoom = await sdk.updateRoom(room.id, {
315
+ name: "New Name",
316
+ description: "New description"
317
+ });
318
+
319
+ expect(updatedRoom.name).toBe("New Name");
320
+ expect(updatedRoom.description).toBe("New description");
321
+ });
322
+
323
+ it("should emit room:updated event", async () => {
324
+ const room = await sdk.createRoom({ name: "Test Room" });
325
+
326
+ const eventPromise = new Promise<RoomInfo>((resolve) => {
327
+ sdk.once("room:updated", (updatedRoom) => {
328
+ resolve(updatedRoom);
329
+ });
330
+ });
331
+
332
+ await sdk.updateRoom(room.id, { name: "Updated" });
333
+ const emittedRoom = await eventPromise;
334
+
335
+ expect(emittedRoom.id).toBe(room.id);
336
+ expect(emittedRoom.name).toBe("Updated");
337
+ });
338
+
339
+ it("should validate update parameters", async () => {
340
+ const room = await sdk.createRoom({ name: "Test Room" });
341
+
342
+ await expect(sdk.updateRoom(room.id, {})).rejects.toThrow("At least one field");
343
+
344
+ await expect(sdk.updateRoom(room.id, { name: "" })).rejects.toThrow(
345
+ "Room name cannot be empty"
346
+ );
347
+ });
348
+ });
349
+
350
+ describe("Room Deletion", () => {
351
+ it("should delete a room", async () => {
352
+ // Create room first
353
+ const room = await sdk.createRoom({ name: "Room to Delete" });
354
+
355
+ expect(sdk.getOwnedRoomCount()).toBe(1);
356
+
357
+ // Delete room
358
+ await sdk.deleteRoom(room.id);
359
+
360
+ // Should be removed from cache
361
+ expect(sdk.getOwnedRoomCount()).toBe(0);
362
+ expect(sdk.getRoomById(room.id)).toBeUndefined();
363
+ });
364
+
365
+ it("should emit room:deleted event", async () => {
366
+ const room = await sdk.createRoom({ name: "Test Room" });
367
+
368
+ const eventPromise = new Promise<string>((resolve) => {
369
+ sdk.once("room:deleted", (roomId) => {
370
+ resolve(roomId);
371
+ });
372
+ });
373
+
374
+ await sdk.deleteRoom(room.id);
375
+ const deletedRoomId = await eventPromise;
376
+
377
+ expect(deletedRoomId).toBe(room.id);
378
+ });
379
+ });
380
+
381
+ describe("Complete Room Lifecycle", () => {
382
+ it("should create, update, and delete a room", async () => {
383
+ // Create
384
+ const room = await sdk.createRoom({
385
+ name: "Lifecycle Test Room",
386
+ description: "Initial description"
387
+ });
388
+
389
+ expect(room.name).toBe("Lifecycle Test Room");
390
+ expect(sdk.getOwnedRoomCount()).toBe(1);
391
+
392
+ // Update
393
+ const updatedRoom = await sdk.updateRoom(room.id, {
394
+ name: "Updated Lifecycle Room",
395
+ description: "Updated description"
396
+ });
397
+
398
+ expect(updatedRoom.name).toBe("Updated Lifecycle Room");
399
+ expect(updatedRoom.description).toBe("Updated description");
400
+ expect(sdk.getOwnedRoomCount()).toBe(1);
401
+
402
+ // Delete
403
+ await sdk.deleteRoom(room.id);
404
+
405
+ expect(sdk.getOwnedRoomCount()).toBe(0);
406
+ expect(sdk.getRoomById(room.id)).toBeUndefined();
407
+ });
408
+ });
409
+
410
+ describe("Room Query Methods", () => {
411
+ it("should get owned rooms", async () => {
412
+ await sdk.createRoom({ name: "Room 1" });
413
+ await sdk.createRoom({ name: "Room 2" });
414
+
415
+ const ownedRooms = sdk.getOwnedRooms();
416
+ expect(ownedRooms).toHaveLength(2);
417
+ });
418
+
419
+ it("should get room by ID", async () => {
420
+ const room = await sdk.createRoom({ name: "Test Room" });
421
+
422
+ const found = sdk.getRoomById(room.id);
423
+ expect(found).toBeDefined();
424
+ expect(found?.name).toBe("Test Room");
425
+ });
426
+
427
+ it("should return undefined for non-existent room", () => {
428
+ const room = sdk.getRoomById("non-existent-id");
429
+ expect(room).toBeUndefined();
430
+ });
431
+
432
+ it("should get owned room count", async () => {
433
+ expect(sdk.getOwnedRoomCount()).toBe(0);
434
+
435
+ await sdk.createRoom({ name: "Room 1" });
436
+ expect(sdk.getOwnedRoomCount()).toBe(1);
437
+
438
+ await sdk.createRoom({ name: "Room 2" });
439
+ expect(sdk.getOwnedRoomCount()).toBe(2);
440
+ });
441
+
442
+ it("should get room limit", () => {
443
+ const limit = sdk.getRoomLimit();
444
+ expect(limit).toBe(5); // Set in mock server
445
+ });
446
+
447
+ it("should check if can create room", () => {
448
+ expect(sdk.canCreateRoom()).toBe(true);
449
+ });
450
+ });
451
+
452
+ describe("Return Value Immutability", () => {
453
+ it("should return defensive copies", async () => {
454
+ await sdk.createRoom({ name: "Test Room" });
455
+
456
+ const rooms1 = sdk.getOwnedRooms();
457
+ const rooms2 = sdk.getOwnedRooms();
458
+
459
+ // Should be different array instances
460
+ expect(rooms1).not.toBe(rooms2);
461
+ // But have same content
462
+ expect(rooms1[0].id).toBe(rooms2[0].id);
463
+
464
+ // Modifying returned array shouldn't affect internal state
465
+ rooms1[0].name = "Modified";
466
+ const rooms3 = sdk.getOwnedRooms();
467
+ expect(rooms3[0].name).not.toBe("Modified");
468
+ });
469
+ });
470
+
471
+ describe("Multiple Rooms", () => {
472
+ it("should handle creating multiple rooms", async () => {
473
+ /* eslint-disable @typescript-eslint/no-unused-vars */
474
+ const room1 = await sdk.createRoom({ name: "Room 1" });
475
+ const room2 = await sdk.createRoom({ name: "Room 2" });
476
+ const room3 = await sdk.createRoom({ name: "Room 3" });
477
+ /* eslint-enable @typescript-eslint/no-unused-vars */
478
+
479
+ expect(sdk.getOwnedRoomCount()).toBe(3);
480
+
481
+ const rooms = sdk.getOwnedRooms();
482
+ expect(rooms.map((r) => r.name)).toContain("Room 1");
483
+ expect(rooms.map((r) => r.name)).toContain("Room 2");
484
+ expect(rooms.map((r) => r.name)).toContain("Room 3");
485
+ });
486
+
487
+ it("should handle updating multiple rooms", async () => {
488
+ const room1 = await sdk.createRoom({ name: "Room 1" });
489
+ const room2 = await sdk.createRoom({ name: "Room 2" });
490
+
491
+ await sdk.updateRoom(room1.id, { name: "Updated Room 1" });
492
+ await sdk.updateRoom(room2.id, { name: "Updated Room 2" });
493
+
494
+ const rooms = sdk.getOwnedRooms();
495
+ expect(rooms.find((r) => r.id === room1.id)?.name).toBe("Updated Room 1");
496
+ expect(rooms.find((r) => r.id === room2.id)?.name).toBe("Updated Room 2");
497
+ });
498
+
499
+ it("should handle deleting multiple rooms", async () => {
500
+ const room1 = await sdk.createRoom({ name: "Room 1" });
501
+ const room2 = await sdk.createRoom({ name: "Room 2" });
502
+ const room3 = await sdk.createRoom({ name: "Room 3" });
503
+
504
+ expect(sdk.getOwnedRoomCount()).toBe(3);
505
+
506
+ await sdk.deleteRoom(room1.id);
507
+ expect(sdk.getOwnedRoomCount()).toBe(2);
508
+
509
+ await sdk.deleteRoom(room2.id);
510
+ expect(sdk.getOwnedRoomCount()).toBe(1);
511
+
512
+ await sdk.deleteRoom(room3.id);
513
+ expect(sdk.getOwnedRoomCount()).toBe(0);
514
+ });
515
+ });
516
+ });
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "vitest";
2
- import WebSocket, { WebSocketServer } from "ws";
2
+ import { WebSocketServer } from "ws";
3
3
  import { TeneoSDK } from "../../src";
4
4
  import { SDKConfigBuilder } from "../../src/types";
5
5
  import { privateKeyToAccount } from "viem/accounts";
@@ -10,6 +10,7 @@ describe("WebSocket Integration Tests", () => {
10
10
  let sdk: TeneoSDK;
11
11
  let serverPort: number;
12
12
  let privateKey: string;
13
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
13
14
  let walletAddress: string;
14
15
 
15
16
  // Mock server to simulate Teneo WebSocket server
@@ -150,6 +151,7 @@ describe("WebSocket Integration Tests", () => {
150
151
  .withAuthentication(privateKey)
151
152
  .withReconnection(false) // Disable for tests
152
153
  .withAutoJoinRooms(["test-room"]) // Auto-join test room
154
+ .withPayments({ autoApprove: false }) // Use legacy flow for mock server
153
155
  .build();
154
156
 
155
157
  sdk = new TeneoSDK(config);
@@ -290,6 +292,7 @@ describe("WebSocket Integration Tests", () => {
290
292
  .withAuthentication(privateKey)
291
293
  .withWebhook("http://localhost:3001/webhook")
292
294
  .withReconnection(false)
295
+ .withPayments({ autoApprove: false }) // Use legacy flow for mock server
293
296
  .build()
294
297
  );
295
298
 
@@ -310,7 +313,7 @@ describe("WebSocket Integration Tests", () => {
310
313
  });
311
314
 
312
315
  describe("Integration with Real Server", () => {
313
- const REAL_SERVER_URL = "wss://dev-rooms-websocket-ai-core-o9fmb.ondigitalocean.app/ws";
316
+ const REAL_SERVER_URL = "wss://your-teneo-server.com/ws";
314
317
  let sdk: TeneoSDK;
315
318
  let privateKey: string;
316
319
 
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Payment Flow Test - Tests the quote-approve payment flow
3
+ *
4
+ * Setup:
5
+ * Create a .env file in the teneo-sdk root with:
6
+ * PRIVATE_KEY=your_private_key_here
7
+ * WS_URL=wss://backend.developer.chatroom.teneo-protocol.ai/ws # optional
8
+ *
9
+ * Run:
10
+ * npx tsx tests/payment-flow-test.ts
11
+ */
12
+
13
+ import "dotenv/config";
14
+ import { TeneoSDK } from "../src/teneo-sdk";
15
+
16
+ // Configuration from environment variables (loaded from .env)
17
+ const WS_URL = process.env.WS_URL || "wss://backend.developer.chatroom.teneo-protocol.ai/ws";
18
+ const PRIVATE_KEY = process.env.PRIVATE_KEY;
19
+
20
+ if (!PRIVATE_KEY) {
21
+ console.error("❌ Missing PRIVATE_KEY");
22
+ console.error("");
23
+ console.error("Setup: Create a .env file in the teneo-sdk root with:");
24
+ console.error(" PRIVATE_KEY=your_private_key_here");
25
+ console.error("");
26
+ console.error("Then run:");
27
+ console.error(" npx tsx tests/payment-flow-test.ts");
28
+ process.exit(1);
29
+ }
30
+
31
+ // Type assertion after validation
32
+ const privateKey: string = PRIVATE_KEY;
33
+
34
+ let TEST_ROOM = ""; // Will be set after auth to use user's private room
35
+
36
+ async function testPaymentFlow() {
37
+ console.log("=== Payment Flow Test ===\n");
38
+ console.log("WebSocket URL:", WS_URL);
39
+
40
+ // Create SDK with quote-approve enabled
41
+ const config = TeneoSDK.builder()
42
+ .withWebSocketUrl(WS_URL)
43
+ .withAuthentication(privateKey)
44
+ .withPayments({
45
+ autoApprove: true,
46
+ maxPricePerRequest: 10_000_000 // Max 10 USDC
47
+ })
48
+ .withLogging("info")
49
+ .build();
50
+
51
+ const sdk = new TeneoSDK(config);
52
+
53
+ // Set up event listeners
54
+ sdk.on("connection:open", () => console.log("✓ Connected"));
55
+ sdk.on("auth:success", (state) => {
56
+ console.log("✓ Authenticated as:", state.walletAddress);
57
+ // Get user's first private room
58
+ if (state.privateRoomIds && state.privateRoomIds.length > 0) {
59
+ TEST_ROOM = state.privateRoomIds[0];
60
+ console.log("✓ Using room:", TEST_ROOM);
61
+ } else if (state.rooms && state.rooms.length > 0) {
62
+ TEST_ROOM = state.rooms[0];
63
+ console.log("✓ Using room:", TEST_ROOM);
64
+ }
65
+ });
66
+ sdk.on("quote:received", (quote) => {
67
+ console.log("\n📋 Quote Received:");
68
+ console.log(" Task ID:", quote.data.task_id);
69
+ console.log(" Agent:", quote.data.agent_name);
70
+ console.log(" Price:", quote.data.pricing.pricePerUnit, "USDC");
71
+ console.log(" Expires:", quote.data.expires_at);
72
+ });
73
+ sdk.on("payment:attached", (data) => {
74
+ console.log("\n💰 Payment Attached:");
75
+ console.log(" Agent:", data.agentId);
76
+ console.log(" Amount:", data.amount / 1_000_000, "USDC");
77
+ console.log(" Command:", data.command);
78
+ });
79
+ sdk.on("agent:response", (response) => {
80
+ console.log("\n📥 Agent Response:");
81
+ console.log(" Success:", response.success);
82
+ console.log(" Content:", response.content.substring(0, 200) + "...");
83
+ });
84
+ sdk.on("error", (error) => console.error("❌ Error:", error.message));
85
+
86
+ try {
87
+ // Connect
88
+ console.log("\nConnecting to", WS_URL);
89
+ await sdk.connect();
90
+ console.log("Connected!\n");
91
+
92
+ // Wait for auth to complete and room to be set
93
+ await sleep(500);
94
+
95
+ if (!TEST_ROOM) {
96
+ throw new Error("No room available - auth may have failed");
97
+ }
98
+
99
+ // Subscribe to test room
100
+ console.log("Subscribing to room:", TEST_ROOM);
101
+ try {
102
+ await sdk.subscribeToRoom(TEST_ROOM);
103
+ console.log("Subscribed!\n");
104
+ } catch {
105
+ console.log("Room subscription skipped (private room)\n");
106
+ }
107
+
108
+ // Wait a bit for connection to stabilize
109
+ await sleep(1000);
110
+
111
+ // Send test message - this will trigger quote-approve flow
112
+ console.log("\n=== Sending Test Request ===");
113
+ console.log('Request: "get me 1 post from @elonmusk from x"\n');
114
+
115
+ const response = await sdk.sendMessage("get me 1 post from @elonmusk from x", {
116
+ room: TEST_ROOM,
117
+ waitForResponse: true,
118
+ timeout: 120000 // 2 minutes
119
+ });
120
+
121
+ if (response) {
122
+ console.log("\n=== Test Complete ===");
123
+ console.log("Response received successfully!");
124
+ console.log(
125
+ "Humanized:",
126
+ typeof response.humanized === "string" ? response.humanized.substring(0, 500) : response
127
+ );
128
+ }
129
+ } catch (error: unknown) {
130
+ const err = error as Error & { details?: unknown };
131
+ console.error("\n❌ Test failed:", err.message);
132
+ if (err.details) {
133
+ console.error("Details:", err.details);
134
+ }
135
+ } finally {
136
+ console.log("\nDisconnecting...");
137
+ sdk.destroy();
138
+ console.log("Done!");
139
+ }
140
+ }
141
+
142
+ function sleep(ms: number): Promise<void> {
143
+ return new Promise((resolve) => setTimeout(resolve, ms));
144
+ }
145
+
146
+ // Run the test
147
+ testPaymentFlow().catch(console.error);