@teneo-protocol/sdk 2.2.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/.github/ISSUE_TEMPLATE/config.yml +1 -1
  2. package/CHANGELOG.md +366 -15
  3. package/CONCEPTS.md +182 -44
  4. package/README.md +524 -94
  5. package/dist/constants.d.ts +3 -1
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +5 -3
  8. package/dist/constants.js.map +1 -1
  9. package/dist/core/websocket-client.d.ts.map +1 -1
  10. package/dist/core/websocket-client.js +9 -5
  11. package/dist/core/websocket-client.js.map +1 -1
  12. package/dist/formatters/response-formatter.d.ts +6 -6
  13. package/dist/handlers/message-handlers/agent-details-response-handler.d.ts +756 -756
  14. package/dist/handlers/message-handlers/agent-details-response-handler.js +2 -2
  15. package/dist/handlers/message-handlers/agent-details-response-handler.js.map +1 -1
  16. package/dist/handlers/message-handlers/agent-error-handler.d.ts +91 -0
  17. package/dist/handlers/message-handlers/agent-error-handler.d.ts.map +1 -0
  18. package/dist/handlers/message-handlers/agent-error-handler.js +44 -0
  19. package/dist/handlers/message-handlers/agent-error-handler.js.map +1 -0
  20. package/dist/handlers/message-handlers/agent-selected-handler.d.ts +6 -0
  21. package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
  22. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +756 -756
  23. package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -1
  24. package/dist/handlers/message-handlers/agent-status-update-handler.js +2 -7
  25. package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -1
  26. package/dist/handlers/message-handlers/all-agents-response-handler.js +2 -2
  27. package/dist/handlers/message-handlers/all-agents-response-handler.js.map +1 -1
  28. package/dist/handlers/message-handlers/auth-error-handler.d.ts +6 -0
  29. package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
  30. package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
  31. package/dist/handlers/message-handlers/auth-message-handler.js +6 -1
  32. package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
  33. package/dist/handlers/message-handlers/auth-required-handler.d.ts +6 -0
  34. package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
  35. package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
  36. package/dist/handlers/message-handlers/auth-success-handler.js +6 -1
  37. package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
  38. package/dist/handlers/message-handlers/base-handler.d.ts +2 -1
  39. package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -1
  40. package/dist/handlers/message-handlers/base-handler.js +24 -4
  41. package/dist/handlers/message-handlers/base-handler.js.map +1 -1
  42. package/dist/handlers/message-handlers/challenge-handler.d.ts +6 -0
  43. package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
  44. package/dist/handlers/message-handlers/error-message-handler.d.ts +6 -0
  45. package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
  46. package/dist/handlers/message-handlers/index.d.ts +4 -0
  47. package/dist/handlers/message-handlers/index.d.ts.map +1 -1
  48. package/dist/handlers/message-handlers/index.js +23 -1
  49. package/dist/handlers/message-handlers/index.js.map +1 -1
  50. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +792 -756
  51. package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -1
  52. package/dist/handlers/message-handlers/list-available-agents-handler.js +23 -10
  53. package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -1
  54. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +756 -756
  55. package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -1
  56. package/dist/handlers/message-handlers/list-room-agents-handler.js +2 -6
  57. package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -1
  58. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
  59. package/dist/handlers/message-handlers/list-rooms-response-handler.js +2 -5
  60. package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -1
  61. package/dist/handlers/message-handlers/ping-pong-handler.d.ts +52 -4
  62. package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
  63. package/dist/handlers/message-handlers/ping-pong-handler.js +23 -4
  64. package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -1
  65. package/dist/handlers/message-handlers/rate-limit-notification-handler.d.ts.map +1 -1
  66. package/dist/handlers/message-handlers/rate-limit-notification-handler.js +3 -2
  67. package/dist/handlers/message-handlers/rate-limit-notification-handler.js.map +1 -1
  68. package/dist/handlers/message-handlers/regular-message-handler.d.ts +6 -0
  69. package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
  70. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +12 -6
  71. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
  72. package/dist/handlers/message-handlers/success-handler.d.ts +82 -0
  73. package/dist/handlers/message-handlers/success-handler.d.ts.map +1 -0
  74. package/dist/handlers/message-handlers/success-handler.js +24 -0
  75. package/dist/handlers/message-handlers/success-handler.js.map +1 -0
  76. package/dist/handlers/message-handlers/task-confirmed-handler.d.ts +110 -0
  77. package/dist/handlers/message-handlers/task-confirmed-handler.d.ts.map +1 -0
  78. package/dist/handlers/message-handlers/task-confirmed-handler.js +46 -0
  79. package/dist/handlers/message-handlers/task-confirmed-handler.js.map +1 -0
  80. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts +244 -0
  81. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.d.ts.map +1 -0
  82. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js +58 -0
  83. package/dist/handlers/message-handlers/trigger-wallet-tx-handler.js.map +1 -0
  84. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +12 -6
  85. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
  86. package/dist/handlers/message-handlers/user-authenticated-handler.js +2 -2
  87. package/dist/handlers/message-handlers/user-authenticated-handler.js.map +1 -1
  88. package/dist/handlers/message-handlers/user-count-handler.js +2 -2
  89. package/dist/handlers/message-handlers/user-count-handler.js.map +1 -1
  90. package/dist/index.d.ts +3 -3
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +11 -4
  93. package/dist/index.js.map +1 -1
  94. package/dist/managers/admin-manager.d.ts +2 -0
  95. package/dist/managers/admin-manager.d.ts.map +1 -1
  96. package/dist/managers/admin-manager.js +3 -2
  97. package/dist/managers/admin-manager.js.map +1 -1
  98. package/dist/managers/agent-room-manager.d.ts +89 -11
  99. package/dist/managers/agent-room-manager.d.ts.map +1 -1
  100. package/dist/managers/agent-room-manager.js +99 -35
  101. package/dist/managers/agent-room-manager.js.map +1 -1
  102. package/dist/managers/index.d.ts +1 -1
  103. package/dist/managers/index.d.ts.map +1 -1
  104. package/dist/managers/index.js.map +1 -1
  105. package/dist/managers/message-router.d.ts +45 -5
  106. package/dist/managers/message-router.d.ts.map +1 -1
  107. package/dist/managers/message-router.js +96 -24
  108. package/dist/managers/message-router.js.map +1 -1
  109. package/dist/managers/room-manager.d.ts +29 -7
  110. package/dist/managers/room-manager.d.ts.map +1 -1
  111. package/dist/managers/room-manager.js +37 -11
  112. package/dist/managers/room-manager.js.map +1 -1
  113. package/dist/payments/index.d.ts +3 -1
  114. package/dist/payments/index.d.ts.map +1 -1
  115. package/dist/payments/index.js +17 -3
  116. package/dist/payments/index.js.map +1 -1
  117. package/dist/payments/networks.d.ts +59 -0
  118. package/dist/payments/networks.d.ts.map +1 -0
  119. package/dist/payments/networks.js +192 -0
  120. package/dist/payments/networks.js.map +1 -0
  121. package/dist/payments/payment-client.d.ts +55 -10
  122. package/dist/payments/payment-client.d.ts.map +1 -1
  123. package/dist/payments/payment-client.js +172 -51
  124. package/dist/payments/payment-client.js.map +1 -1
  125. package/dist/teneo-sdk.d.ts +214 -40
  126. package/dist/teneo-sdk.d.ts.map +1 -1
  127. package/dist/teneo-sdk.js +360 -83
  128. package/dist/teneo-sdk.js.map +1 -1
  129. package/dist/types/config.d.ts +334 -25
  130. package/dist/types/config.d.ts.map +1 -1
  131. package/dist/types/config.js +114 -22
  132. package/dist/types/config.js.map +1 -1
  133. package/dist/types/events.d.ts +60 -14
  134. package/dist/types/events.d.ts.map +1 -1
  135. package/dist/types/events.js.map +1 -1
  136. package/dist/types/index.d.ts +1 -1
  137. package/dist/types/index.d.ts.map +1 -1
  138. package/dist/types/index.js +11 -4
  139. package/dist/types/index.js.map +1 -1
  140. package/dist/types/messages.d.ts +9801 -7222
  141. package/dist/types/messages.d.ts.map +1 -1
  142. package/dist/types/messages.js +180 -40
  143. package/dist/types/messages.js.map +1 -1
  144. package/dist/utils/pricing-resolver.d.ts +1 -1
  145. package/dist/utils/pricing-resolver.d.ts.map +1 -1
  146. package/dist/utils/pricing-resolver.js +9 -1
  147. package/dist/utils/pricing-resolver.js.map +1 -1
  148. package/examples/agent-room-management-example.ts +5 -5
  149. package/examples/basic-usage.ts +26 -6
  150. package/examples/claude-agent-x-follower/index.ts +1 -1
  151. package/examples/minimal-chat.ts +4 -3
  152. package/examples/n8n-teneo/index.ts +2 -2
  153. package/examples/nestjs-dashboard/README.md +1 -1
  154. package/examples/nestjs-dashboard/src/teneo/agents.controller.ts +3 -3
  155. package/examples/nestjs-dashboard/src/teneo/rooms.controller.ts +5 -5
  156. package/examples/nestjs-dashboard/src/teneo/teneo.service.ts +8 -8
  157. package/examples/openai-teneo/index.ts +1 -1
  158. package/examples/payment-flow.ts +143 -0
  159. package/examples/production-dashboard/README.md +6 -8
  160. package/examples/production-dashboard/server.ts +22 -10
  161. package/examples/room-management-example.ts +2 -2
  162. package/examples/usage/01-connect.ts +0 -3
  163. package/examples/usage/02-list-agents.ts +0 -2
  164. package/examples/usage/03-pick-agent.ts +3 -4
  165. package/examples/usage/04-find-by-capability.ts +10 -12
  166. package/examples/usage/05-webhook-example.ts +2 -4
  167. package/examples/usage/06-simple-api-server.ts +13 -9
  168. package/examples/usage/07-event-listener.ts +1 -13
  169. package/examples/usage/README.md +33 -7
  170. package/examples/webhook-integration.ts +9 -9
  171. package/examples/x-influencer-battle-server.ts +1 -1
  172. package/package.json +1 -1
  173. package/scripts/diagnose-connection.ts +86 -0
  174. package/scripts/investigate-payload.ts +163 -0
  175. package/scripts/list-agents.ts +58 -0
  176. package/scripts/live-multi-network-test.ts +230 -0
  177. package/src/constants.ts +5 -3
  178. package/src/core/websocket-client.ts +10 -9
  179. package/src/handlers/message-handlers/agent-details-response-handler.ts +2 -2
  180. package/src/handlers/message-handlers/agent-error-handler.ts +47 -0
  181. package/src/handlers/message-handlers/agent-status-update-handler.ts +2 -7
  182. package/src/handlers/message-handlers/all-agents-response-handler.ts +2 -2
  183. package/src/handlers/message-handlers/auth-message-handler.ts +7 -1
  184. package/src/handlers/message-handlers/auth-success-handler.ts +7 -1
  185. package/src/handlers/message-handlers/base-handler.ts +24 -4
  186. package/src/handlers/message-handlers/index.ts +24 -0
  187. package/src/handlers/message-handlers/list-available-agents-handler.ts +24 -11
  188. package/src/handlers/message-handlers/list-room-agents-handler.ts +2 -6
  189. package/src/handlers/message-handlers/list-rooms-response-handler.ts +2 -5
  190. package/src/handlers/message-handlers/ping-pong-handler.ts +29 -4
  191. package/src/handlers/message-handlers/rate-limit-notification-handler.ts +3 -2
  192. package/src/handlers/message-handlers/success-handler.ts +26 -0
  193. package/src/handlers/message-handlers/task-confirmed-handler.ts +49 -0
  194. package/src/handlers/message-handlers/trigger-wallet-tx-handler.ts +62 -0
  195. package/src/handlers/message-handlers/user-authenticated-handler.ts +2 -2
  196. package/src/handlers/message-handlers/user-count-handler.ts +2 -2
  197. package/src/index.ts +12 -4
  198. package/src/managers/admin-manager.ts +5 -2
  199. package/src/managers/agent-room-manager.ts +155 -26
  200. package/src/managers/index.ts +6 -1
  201. package/src/managers/message-router.ts +122 -27
  202. package/src/managers/room-manager.ts +39 -11
  203. package/src/payments/index.ts +20 -5
  204. package/src/payments/networks.ts +208 -0
  205. package/src/payments/payment-client.ts +211 -56
  206. package/src/teneo-sdk.ts +401 -70
  207. package/src/types/config.test.ts +24 -4
  208. package/src/types/config.ts +123 -25
  209. package/src/types/events.ts +36 -2
  210. package/src/types/index.ts +16 -3
  211. package/src/types/messages.ts +221 -57
  212. package/src/utils/pricing-resolver.ts +10 -2
  213. package/tests/direct-agent-test.ts +1 -1
  214. package/tests/integration/real-server.test.ts +1 -1
  215. package/tests/integration/websocket.test.ts +3 -3
  216. package/tests/multi-network-payment.test.ts +309 -0
  217. package/tests/multi-network.test.ts +296 -0
  218. package/tests/payment-flow-test.ts +6 -4
  219. package/tests/unit/handlers/agent-error-handler.test.ts +388 -0
  220. package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +9 -6
  221. package/tests/unit/handlers/agent-status-update-handler.test.ts +11 -16
  222. package/tests/unit/handlers/list-available-agents-handler.test.ts +11 -14
  223. package/tests/unit/handlers/list-room-agents-handler.test.ts +11 -15
  224. package/tests/unit/handlers/room-operation-response-handler.test.ts +9 -6
  225. package/tests/unit/handlers/trigger-wallet-tx-handler.test.ts +431 -0
  226. package/tests/unit/managers/admin-manager.test.ts +183 -0
  227. package/tests/unit/managers/agent-room-manager.test.ts +189 -33
  228. package/tests/unit/sdk-new-methods.test.ts +221 -0
package/src/constants.ts CHANGED
@@ -15,7 +15,9 @@ export const TIMEOUTS = {
15
15
  /** Webhook delivery timeout */
16
16
  WEBHOOK_TIMEOUT: 10_000,
17
17
  /** Auth state polling interval */
18
- AUTH_POLL_INTERVAL: 100
18
+ AUTH_POLL_INTERVAL: 100,
19
+ /** Time window for matching responses without client_request_id (fallback) */
20
+ RESPONSE_MATCH_WINDOW: 60_000
19
21
  } as const;
20
22
 
21
23
  /**
@@ -36,8 +38,8 @@ export const RETRY = {
36
38
  * Limits and constraints
37
39
  */
38
40
  export const LIMITS = {
39
- /** Maximum message size (2MB) */
40
- MAX_MESSAGE_SIZE: 2 * 1024 * 1024,
41
+ /** Maximum message size (10MB - sufficient for room history) */
42
+ MAX_MESSAGE_SIZE: 10 * 1024 * 1024,
41
43
  /** Random jitter for reconnection */
42
44
  MAX_JITTER: 1000
43
45
  } as const;
@@ -338,16 +338,14 @@ export class WebSocketClient extends EventEmitter<SDKEvents> {
338
338
  if (parseResult.success) {
339
339
  this.handleMessage(parseResult.data as BaseMessage);
340
340
  } else {
341
- // Use warn instead of error - allows SDK to be more resilient
342
- this.logger.warn("Received message with unknown or invalid format", {
341
+ // Log validation errors at debug level only (hidden from end users)
342
+ this.logger.debug("Message validation warning", {
343
343
  type: rawMessage?.type,
344
344
  error: parseResult.error?.message
345
345
  });
346
- this.emit(
347
- "message:error",
348
- new ValidationError("Invalid message format", parseResult.error),
349
- rawMessage
350
- );
346
+
347
+ // Still process the message for resilience - don't block on validation errors
348
+ this.handleMessage(rawMessage as BaseMessage);
351
349
  }
352
350
  } catch (error) {
353
351
  this.logger.error("Failed to parse message", error);
@@ -618,8 +616,11 @@ export class WebSocketClient extends EventEmitter<SDKEvents> {
618
616
  try {
619
617
  // Check for cached authentication first
620
618
  if (this.config.walletAddress) {
621
- this.logger.debug("Checking cached authentication");
622
- await this.sendMessage(createCheckCachedAuth(this.config.walletAddress));
619
+ const sessionToken = this.authState.sessionToken;
620
+ this.logger.debug("Checking cached authentication", {
621
+ hasSessionToken: !!sessionToken
622
+ });
623
+ await this.sendMessage(createCheckCachedAuth(this.config.walletAddress, sessionToken));
623
624
 
624
625
  // Wait briefly for cached auth response
625
626
  await new Promise((resolve) => setTimeout(resolve, TIMEOUTS.CACHED_AUTH_WAIT));
@@ -36,7 +36,7 @@ export class AgentDetailsResponseHandler extends BaseMessageHandler<AgentDetails
36
36
  status: agent.status
37
37
  });
38
38
 
39
- // Send webhook
40
- this.sendWebhook(context, "agent_details_response", { agent });
39
+ // Note: This is a query response, not sent via webhook
40
+ // Users can listen to the 'agent:details' event if needed
41
41
  }
42
42
  }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Handler for agent_error messages
3
+ * Processes agent failure notifications from the server (no payment charged)
4
+ */
5
+
6
+ import { AgentErrorMessage, AgentErrorMessageSchema } from "../../types";
7
+ import { BaseMessageHandler } from "./base-handler";
8
+ import { HandlerContext } from "./types";
9
+
10
+ export class AgentErrorHandler extends BaseMessageHandler<AgentErrorMessage> {
11
+ readonly type = "agent_error" as const;
12
+ readonly schema = AgentErrorMessageSchema;
13
+
14
+ protected handleValidated(message: AgentErrorMessage, context: HandlerContext): void {
15
+ const { content, from, data, room } = message;
16
+
17
+ context.logger.debug("Handling agent_error", {
18
+ from,
19
+ taskId: data?.task_id,
20
+ content
21
+ });
22
+
23
+ context.logger.warn("Agent error received", {
24
+ agentName: from,
25
+ content,
26
+ taskId: data?.task_id
27
+ });
28
+
29
+ // Emit agent error event
30
+ this.emit(context, "agent:error", {
31
+ agentName: from,
32
+ content,
33
+ taskId: data?.task_id,
34
+ clientRequestId: data?.client_request_id,
35
+ room
36
+ });
37
+
38
+ // Send webhook
39
+ this.sendWebhook(context, "agent_error", {
40
+ agentName: from,
41
+ content,
42
+ taskId: data?.task_id,
43
+ clientRequestId: data?.client_request_id,
44
+ room
45
+ });
46
+ }
47
+ }
@@ -41,12 +41,7 @@ export class AgentStatusUpdateHandler extends BaseMessageHandler<AgentStatusUpda
41
41
  agent
42
42
  });
43
43
 
44
- // Send webhook
45
- this.sendWebhook(context, "agent_status_update", {
46
- room_id,
47
- agent_id,
48
- status,
49
- agent
50
- });
44
+ // Note: Agent status updates fire constantly and would spam webhooks
45
+ // Users can listen to the 'agent_room:status_update' event if needed
51
46
  }
52
47
  }
@@ -33,7 +33,7 @@ export class AllAgentsResponseHandler extends BaseMessageHandler<AllAgentsRespon
33
33
  filter
34
34
  });
35
35
 
36
- // Send webhook
37
- this.sendWebhook(context, "all_agents_response", message.data);
36
+ // Note: This is a query response, not sent via webhook
37
+ // Admins can listen to the 'admin:all_agents' event if needed
38
38
  }
39
39
  }
@@ -65,7 +65,13 @@ export class AuthMessageHandler extends BaseMessageHandler<AuthMessage> {
65
65
  // v2.0.0: New fields
66
66
  privateRoomIds, // Rooms user owns
67
67
  sharedRoomIds, // Rooms user is member of
68
- maxPrivateRooms: message.data?.max_private_rooms // Max rooms user can create
68
+ maxPrivateRooms: message.data?.max_private_rooms, // Max rooms user can create
69
+
70
+ // Auth enhancement fields (audit #6, #7, #9)
71
+ jwtToken: message.data?.jwt_token, // JWT token for KeyVault API
72
+ sessionToken: message.data?.session_token, // Session token for fast re-auth
73
+ whitelistVerified: message.data?.whitelist_verified, // Whitelist verification status
74
+ userCount: message.data?.user_count // Total user count (admin only)
69
75
  });
70
76
 
71
77
  // Initialize room management manager with room data (v2.0.0)
@@ -42,7 +42,13 @@ export class AuthSuccessHandler extends BaseMessageHandler<AuthSuccessMessage> {
42
42
  roomObjects: rooms, // Full room objects with is_owner field
43
43
  privateRoomIds, // Rooms user owns
44
44
  sharedRoomIds, // Rooms user is member of
45
- maxPrivateRooms: message.data.max_private_rooms // Max rooms user can create
45
+ maxPrivateRooms: message.data.max_private_rooms, // Max rooms user can create
46
+
47
+ // Auth enhancement fields (audit #6, #7, #9)
48
+ jwtToken: message.data.jwt_token, // JWT token for KeyVault API
49
+ sessionToken: message.data.session_token, // Session token for fast re-auth
50
+ whitelistVerified: message.data.whitelist_verified, // Whitelist verification status
51
+ userCount: message.data.user_count // Total user count (admin only)
46
52
  });
47
53
 
48
54
  // Get updated auth state
@@ -34,10 +34,29 @@ export abstract class BaseMessageHandler<T extends BaseMessage = BaseMessage>
34
34
  public async handle(message: BaseMessage, context: HandlerContext): Promise<void> {
35
35
  try {
36
36
  // Validate message with Zod schema
37
- const validated = this.validate(message);
37
+ const result = this.schema.safeParse(message);
38
+ if (!result.success) {
39
+ // Log validation errors at debug level only (hidden from end users)
40
+ context.logger.debug(`${this.type} message validation warning`, {
41
+ error: result.error.message
42
+ });
43
+ }
38
44
 
39
- // Call subclass implementation
40
- await this.handleValidated(validated, context);
45
+ // Process message even if validation failed (resilience)
46
+ // Use validated data if available, otherwise use raw message
47
+ const messageToProcess = result.success ? result.data : (message as T);
48
+
49
+ // Call subclass implementation with additional error protection
50
+ try {
51
+ await this.handleValidated(messageToProcess, context);
52
+ } catch (handlerError) {
53
+ // Catch errors from handlers accessing malformed data
54
+ context.logger.warn(`Handler ${this.type} failed to process message`, {
55
+ error: handlerError instanceof Error ? handlerError.message : String(handlerError),
56
+ messageType: message.type
57
+ });
58
+ // Don't re-throw - resilient processing continues
59
+ }
41
60
  } catch (error) {
42
61
  context.logger.error(`Error handling ${this.type} message`, error);
43
62
  this.onError(error, message, context);
@@ -45,7 +64,8 @@ export abstract class BaseMessageHandler<T extends BaseMessage = BaseMessage>
45
64
  }
46
65
 
47
66
  /**
48
- * Validate message against schema
67
+ * Validate message against schema (deprecated - validation now inline in handle())
68
+ * @deprecated Validation is now done inline in handle() method
49
69
  */
50
70
  protected validate(message: BaseMessage): T {
51
71
  const result = this.schema.safeParse(message);
@@ -18,6 +18,7 @@ export { AuthErrorHandler } from "./auth-error-handler";
18
18
  export { AuthRequiredHandler } from "./auth-required-handler";
19
19
  export { AgentsListHandler } from "./agents-list-handler";
20
20
  export { ErrorMessageHandler } from "./error-message-handler";
21
+ export { SuccessHandler } from "./success-handler";
21
22
  export { RegularMessageHandler } from "./regular-message-handler";
22
23
  export { PingHandler, PongHandler } from "./ping-pong-handler";
23
24
  export { SubscribeResponseHandler } from "./subscribe-response-handler";
@@ -39,6 +40,15 @@ export { RateLimitNotificationHandler } from "./rate-limit-notification-handler"
39
40
  export { AllAgentsResponseHandler } from "./all-agents-response-handler";
40
41
  export { UserCountHandler } from "./user-count-handler";
41
42
 
43
+ // Agent Error handler
44
+ export { AgentErrorHandler } from "./agent-error-handler";
45
+
46
+ // Task Confirmed handler
47
+ export { TaskConfirmedHandler } from "./task-confirmed-handler";
48
+
49
+ // Wallet Transaction handler
50
+ export { TriggerWalletTxHandler } from "./trigger-wallet-tx-handler";
51
+
42
52
  // Presence handler
43
53
  export { UserAuthenticatedHandler } from "./user-authenticated-handler";
44
54
 
@@ -53,6 +63,7 @@ import { AuthErrorHandler } from "./auth-error-handler";
53
63
  import { AuthRequiredHandler } from "./auth-required-handler";
54
64
  import { AgentsListHandler } from "./agents-list-handler";
55
65
  import { ErrorMessageHandler } from "./error-message-handler";
66
+ import { SuccessHandler } from "./success-handler";
56
67
  import { RegularMessageHandler } from "./regular-message-handler";
57
68
  import { PingHandler, PongHandler } from "./ping-pong-handler";
58
69
  import { SubscribeResponseHandler } from "./subscribe-response-handler";
@@ -67,6 +78,9 @@ import { AgentDetailsResponseHandler } from "./agent-details-response-handler";
67
78
  import { RateLimitNotificationHandler } from "./rate-limit-notification-handler";
68
79
  import { AllAgentsResponseHandler } from "./all-agents-response-handler";
69
80
  import { UserCountHandler } from "./user-count-handler";
81
+ import { AgentErrorHandler } from "./agent-error-handler";
82
+ import { TaskConfirmedHandler } from "./task-confirmed-handler";
83
+ import { TriggerWalletTxHandler } from "./trigger-wallet-tx-handler";
70
84
  import { UserAuthenticatedHandler } from "./user-authenticated-handler";
71
85
  import { MessageHandler } from "./types";
72
86
 
@@ -95,6 +109,7 @@ export function getDefaultHandlers(
95
109
  // Message handlers
96
110
  new RegularMessageHandler(),
97
111
  new ErrorMessageHandler(),
112
+ new SuccessHandler(),
98
113
 
99
114
  // Room handlers
100
115
  new SubscribeResponseHandler(),
@@ -120,6 +135,15 @@ export function getDefaultHandlers(
120
135
  new AllAgentsResponseHandler(),
121
136
  new UserCountHandler(),
122
137
 
138
+ // Agent Error handler
139
+ new AgentErrorHandler(),
140
+
141
+ // Task Confirmed handler
142
+ new TaskConfirmedHandler(),
143
+
144
+ // Wallet Transaction handler
145
+ new TriggerWalletTxHandler(),
146
+
123
147
  // Presence handler
124
148
  new UserAuthenticatedHandler(),
125
149
 
@@ -13,29 +13,42 @@ export class ListAvailableAgentsHandler extends BaseMessageHandler<AvailableAgen
13
13
  readonly schema = AvailableAgentsResponseSchema;
14
14
 
15
15
  protected handleValidated(message: AvailableAgentsResponse, context: HandlerContext): void {
16
- const { agents } = message.data;
16
+ const { agents, total, offset, limit, has_more } = message.data;
17
17
 
18
18
  context.logger.debug("Handling available_agents_response", {
19
- agentCount: agents?.length || 0
19
+ agentCount: agents?.length || 0,
20
+ total,
21
+ offset,
22
+ limit,
23
+ has_more
20
24
  });
21
25
 
22
26
  // Parse agents array (handle undefined as empty array)
23
27
  const agentList: AgentRoomInfo[] = agents || [];
24
28
 
25
29
  context.logger.info("Available agents listed", {
26
- count: agentList.length
30
+ count: agentList.length,
31
+ total
27
32
  });
28
33
 
29
34
  // Note: We don't cache this globally since it's room-specific
30
35
  // The AgentRoomManager will cache it with the room context
31
36
 
32
- // Emit success event
33
- this.emit(context, "agent_room:available_agents_listed", agentList);
34
-
35
- // Send webhook
36
- this.sendWebhook(context, "available_agents_listed", {
37
- agents: agentList,
38
- count: agentList.length
39
- });
37
+ // Emit success event, with pagination metadata if present
38
+ const hasPagination =
39
+ total !== undefined || offset !== undefined || limit !== undefined || has_more !== undefined;
40
+ if (hasPagination) {
41
+ this.emit(context, "agent_room:available_agents_listed", agentList, {
42
+ total,
43
+ offset,
44
+ limit,
45
+ hasMore: has_more
46
+ });
47
+ } else {
48
+ this.emit(context, "agent_room:available_agents_listed", agentList);
49
+ }
50
+
51
+ // Note: This is a query response, not sent via webhook
52
+ // Users can listen to the 'agent_room:available_agents_listed' event if needed
40
53
  }
41
54
  }
@@ -48,11 +48,7 @@ export class ListRoomAgentsHandler extends BaseMessageHandler<RoomAgentsResponse
48
48
  // Emit success event
49
49
  this.emit(context, "agent_room:agents_listed", room_id, agentList);
50
50
 
51
- // Send webhook
52
- this.sendWebhook(context, "room_agents_listed", {
53
- room_id,
54
- agents: agentList,
55
- count: agentList.length
56
- });
51
+ // Note: This is a query response, not sent via webhook
52
+ // Users can listen to the 'agent_room:agents_listed' event if needed
57
53
  }
58
54
  }
@@ -21,10 +21,7 @@ export class ListRoomsResponseHandler extends BaseMessageHandler<ListRoomsRespon
21
21
  // Emit room:list event with room info array
22
22
  this.emit(context, "room:list", message.data.rooms);
23
23
 
24
- // Send webhook (fire-and-forget)
25
- this.sendWebhook(context, "room_list", {
26
- rooms: message.data.rooms,
27
- count: message.data.rooms.length
28
- });
24
+ // Note: This is a query response, not sent via webhook
25
+ // Users can listen to the 'room:list' event if needed
29
26
  }
30
27
  }
@@ -22,9 +22,34 @@ export class PongHandler extends BaseMessageHandler<PongMessage> {
22
22
  readonly type = "pong" as const;
23
23
  readonly schema = PongMessageSchema;
24
24
 
25
- protected async handleValidated(_message: PongMessage, context: HandlerContext): Promise<void> {
26
- // Pong messages are handled at the WebSocket level (ws library)
27
- // No special processing needed here
28
- context.logger.debug("Received pong");
25
+ protected async handleValidated(message: PongMessage, context: HandlerContext): Promise<void> {
26
+ // Check if this is a room pong (has room data) or regular pong
27
+ if (message.data && typeof message.data === "object" && "room_id" in message.data) {
28
+ // Room pong - server responds to room_ping with live user count
29
+ const roomData = message.data as {
30
+ room_id: string;
31
+ live_count?: number;
32
+ timestamp: string;
33
+ };
34
+
35
+ context.logger.debug("Received room pong", {
36
+ roomId: roomData.room_id,
37
+ liveCount: roomData.live_count,
38
+ timestamp: roomData.timestamp
39
+ });
40
+
41
+ // Emit room pong event
42
+ this.emit(context, "room:pong", {
43
+ roomId: roomData.room_id,
44
+ liveCount: roomData.live_count ?? 0,
45
+ timestamp: roomData.timestamp
46
+ });
47
+
48
+ // Note: room_pong is an internal keepalive/user-count event, not sent via webhook
49
+ // Users can listen to the 'room:pong' event if needed
50
+ } else {
51
+ // Regular pong - handled at the WebSocket level (ws library)
52
+ context.logger.debug("Received pong");
53
+ }
29
54
  }
30
55
  }
@@ -39,7 +39,8 @@ export class RateLimitNotificationHandler extends BaseMessageHandler<RateLimitNo
39
39
  resetAt: reset_at
40
40
  });
41
41
 
42
- // Send webhook
43
- this.sendWebhook(context, "rate_limit_notification", message.data);
42
+ // Note: Rate limits are already logged and handled internally
43
+ // Sending via webhook would be redundant
44
+ // Users can listen to the 'rate_limit' event if needed
44
45
  }
45
46
  }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Handler for success messages
3
+ * Server sends generic success confirmations that can be displayed to users
4
+ */
5
+
6
+ import { SuccessMessage, SuccessMessageSchema } from "../../types";
7
+ import { BaseMessageHandler } from "./base-handler";
8
+ import { HandlerContext } from "./types";
9
+
10
+ export class SuccessHandler extends BaseMessageHandler<SuccessMessage> {
11
+ readonly type = "success" as const;
12
+ readonly schema = SuccessMessageSchema;
13
+
14
+ protected handleValidated(message: SuccessMessage, context: HandlerContext): void {
15
+ const content = message.content || message.data?.content;
16
+
17
+ context.logger.debug("Handling success message", { content });
18
+
19
+ // Emit success event
20
+ this.emit(context, "success", content || "Operation successful");
21
+
22
+ // Note: Generic success messages are too vague for webhooks
23
+ // Specific success events (room_operation, etc.) have their own handlers
24
+ // Users can listen to the 'success' event if needed
25
+ }
26
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Handler for task_confirmed messages
3
+ * Server sends this as acknowledgment after confirm_task in the Quote-Confirm flow.
4
+ * Indicates that task execution has begun.
5
+ */
6
+
7
+ import { TaskConfirmedMessage, TaskConfirmedMessageSchema } from "../../types";
8
+ import { BaseMessageHandler } from "./base-handler";
9
+ import { HandlerContext } from "./types";
10
+
11
+ export class TaskConfirmedHandler extends BaseMessageHandler<TaskConfirmedMessage> {
12
+ readonly type = "task_confirmed" as const;
13
+ readonly schema = TaskConfirmedMessageSchema;
14
+
15
+ protected handleValidated(message: TaskConfirmedMessage, context: HandlerContext): void {
16
+ const taskId = message.data?.task_id ?? message.task_id ?? "";
17
+ const agentId = message.data?.agent_id;
18
+ const agentName = message.data?.agent_name;
19
+ const clientRequestId = message.data?.client_request_id;
20
+
21
+ context.logger.debug("Handling task_confirmed", {
22
+ taskId,
23
+ agentId,
24
+ agentName
25
+ });
26
+
27
+ context.logger.info("Task confirmed and execution started", {
28
+ taskId,
29
+ agentId,
30
+ agentName
31
+ });
32
+
33
+ // Emit task confirmed event
34
+ this.emit(context, "task:confirmed", {
35
+ taskId,
36
+ agentId,
37
+ agentName,
38
+ clientRequestId
39
+ });
40
+
41
+ // Send webhook
42
+ this.sendWebhook(context, "task_confirmed", {
43
+ taskId,
44
+ agentId,
45
+ agentName,
46
+ clientRequestId
47
+ });
48
+ }
49
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Handler for trigger_wallet_tx messages
3
+ * Server sends this when an agent requires an on-chain transaction
4
+ */
5
+
6
+ import { TriggerWalletTxMessage, TriggerWalletTxMessageSchema } from "../../types";
7
+ import { BaseMessageHandler } from "./base-handler";
8
+ import { HandlerContext } from "./types";
9
+
10
+ export class TriggerWalletTxHandler extends BaseMessageHandler<TriggerWalletTxMessage> {
11
+ readonly type = "trigger_wallet_tx" as const;
12
+ readonly schema = TriggerWalletTxMessageSchema;
13
+
14
+ protected handleValidated(message: TriggerWalletTxMessage, context: HandlerContext): void {
15
+ const { from, data, room } = message;
16
+
17
+ // Defensive: Check for required fields
18
+ if (!data?.task_id || !data?.tx) {
19
+ context.logger.warn("Invalid trigger_wallet_tx message: missing required fields", {
20
+ from,
21
+ hasData: !!data,
22
+ hasTaskId: !!data?.task_id,
23
+ hasTx: !!data?.tx
24
+ });
25
+ return;
26
+ }
27
+
28
+ context.logger.debug("Handling trigger_wallet_tx", {
29
+ from,
30
+ taskId: data.task_id,
31
+ tx: data.tx
32
+ });
33
+
34
+ context.logger.info("Wallet transaction requested", {
35
+ agentName: from,
36
+ taskId: data.task_id,
37
+ to: data.tx.to,
38
+ value: data.tx.value,
39
+ chainId: data.tx.chainId
40
+ });
41
+
42
+ // Emit wallet tx requested event
43
+ this.emit(context, "wallet:tx_requested", {
44
+ taskId: data.task_id,
45
+ agentName: from,
46
+ tx: data.tx,
47
+ description: data.description,
48
+ optional: data.optional ?? false,
49
+ room
50
+ });
51
+
52
+ // Send webhook
53
+ this.sendWebhook(context, "wallet_tx_requested", {
54
+ taskId: data.task_id,
55
+ agentName: from,
56
+ tx: data.tx,
57
+ description: data.description,
58
+ optional: data.optional,
59
+ room
60
+ });
61
+ }
62
+ }
@@ -25,7 +25,7 @@ export class UserAuthenticatedHandler extends BaseMessageHandler<UserAuthenticat
25
25
  // Emit presence event
26
26
  this.emit(context, "user:authenticated", { wallet });
27
27
 
28
- // Send webhook
29
- this.sendWebhook(context, "user_authenticated", message.data);
28
+ // Note: user_authenticated is not in the WebhookEventType enum, so no webhook is sent
29
+ // This is a broadcast event for presence tracking, not typically needed in webhooks
30
30
  }
31
31
  }
@@ -28,7 +28,7 @@ export class UserCountHandler extends BaseMessageHandler<UserCountMessage> {
28
28
  // Emit admin event
29
29
  this.emit(context, "admin:user_count", { count, timestamp });
30
30
 
31
- // Send webhook
32
- this.sendWebhook(context, "user_count", message.data);
31
+ // Note: user_count is not in the WebhookEventType enum, so no webhook is sent
32
+ // This is an admin-only broadcast event, not typically needed in webhooks
33
33
  }
34
34
  }
package/src/index.ts CHANGED
@@ -243,20 +243,28 @@ export {
243
243
  PEAQ_CHAIN_ID,
244
244
  USDC_CONTRACT,
245
245
  DEFAULT_PAY_TO_ADDRESS,
246
- DEFAULT_RPC_URL,
247
246
  USDC_DECIMALS,
248
247
  X402_VERSION,
249
248
  DEFAULT_PAYMENT_TIMEOUT_SECONDS,
250
249
  buildX402ResourceUrl,
251
250
  usdcToUnits,
252
251
  unitsToUsdc,
253
- type SupportedChain
252
+ // Multi-network support (v2.3.0)
253
+ type NetworkConfig,
254
+ NETWORKS,
255
+ CHAIN_ID_TO_NETWORK,
256
+ CAIP2_TO_NETWORK,
257
+ getNetwork,
258
+ getDefaultNetwork,
259
+ createChainDefinition,
260
+ isNetworkSupported,
261
+ getSupportedNetworks
254
262
  } from "./payments";
255
263
 
256
264
  /**
257
265
  * SDK version string
258
266
  */
259
- export const VERSION = "2.2.2";
267
+ export const VERSION = "3.0.0";
260
268
 
261
269
  /**
262
270
  * Convenience type re-exports for message operations
@@ -275,7 +283,7 @@ export type { SendMessageOptions, AgentCommand } from "./teneo-sdk";
275
283
  * const sdk = await createTeneoSDK({
276
284
  * wsUrl: 'ws://localhost:8080/ws',
277
285
  * privateKey: 'your-private-key',
278
- * autoJoinRooms: ['general']
286
+ * autoJoinPublicRooms: ['room-id-1']
279
287
  * });
280
288
  * ```
281
289
  */
@@ -30,6 +30,8 @@ export interface ListAllAgentsOptions {
30
30
  offset?: number;
31
31
  /** Number of agents to return (default: 50) */
32
32
  limit?: number;
33
+ /** Sort order: alphabetical or by request count */
34
+ sortBy?: "a-z" | "requests";
33
35
  }
34
36
 
35
37
  /**
@@ -124,9 +126,9 @@ export class AdminManager extends EventEmitter<AdminManagerEvents> {
124
126
  throw new SDKError("Admin privileges required", ErrorCode.AUTH_ERROR);
125
127
  }
126
128
 
127
- const { filter, offset = 0, limit = 50 } = options;
129
+ const { filter, offset = 0, limit = 50, sortBy } = options;
128
130
 
129
- this.logger.info("AdminManager: Listing all agents", { filter, offset, limit });
131
+ this.logger.info("AdminManager: Listing all agents", { filter, offset, limit, sortBy });
130
132
 
131
133
  // Generate request ID
132
134
  const requestId = `admin_list_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
@@ -137,6 +139,7 @@ export class AdminManager extends EventEmitter<AdminManagerEvents> {
137
139
  filter,
138
140
  offset,
139
141
  limit,
142
+ ...(sortBy && { sort_by: sortBy }),
140
143
  request_id: requestId
141
144
  };
142
145