@teneo-protocol/sdk 1.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.
- package/.dockerignore +14 -0
- package/.env.test.example +14 -0
- package/.eslintrc.json +26 -0
- package/.github/workflows/claude-code-review.yml +78 -0
- package/.github/workflows/claude-reviewer.yml +64 -0
- package/.github/workflows/publish-npm.yml +38 -0
- package/.github/workflows/push-to-main.yml +23 -0
- package/.node-version +1 -0
- package/.prettierrc +11 -0
- package/Dockerfile +25 -0
- package/LICENCE +661 -0
- package/README.md +709 -0
- package/dist/constants.d.ts +42 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +45 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/websocket-client.d.ts +261 -0
- package/dist/core/websocket-client.d.ts.map +1 -0
- package/dist/core/websocket-client.js +875 -0
- package/dist/core/websocket-client.js.map +1 -0
- package/dist/formatters/response-formatter.d.ts +354 -0
- package/dist/formatters/response-formatter.d.ts.map +1 -0
- package/dist/formatters/response-formatter.js +575 -0
- package/dist/formatters/response-formatter.js.map +1 -0
- package/dist/handlers/message-handler-registry.d.ts +155 -0
- package/dist/handlers/message-handler-registry.d.ts.map +1 -0
- package/dist/handlers/message-handler-registry.js +216 -0
- package/dist/handlers/message-handler-registry.js.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts +112 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.js +40 -0
- package/dist/handlers/message-handlers/agent-selected-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agents-list-handler.d.ts +14 -0
- package/dist/handlers/message-handlers/agents-list-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agents-list-handler.js +25 -0
- package/dist/handlers/message-handlers/agents-list-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts +71 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/auth-error-handler.js +30 -0
- package/dist/handlers/message-handlers/auth-error-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-message-handler.d.ts +18 -0
- package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/auth-message-handler.js +60 -0
- package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-required-handler.d.ts +76 -0
- package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/auth-required-handler.js +23 -0
- package/dist/handlers/message-handlers/auth-required-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-success-handler.d.ts +18 -0
- package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/auth-success-handler.js +51 -0
- package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -0
- package/dist/handlers/message-handlers/base-handler.d.ts +55 -0
- package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/base-handler.js +83 -0
- package/dist/handlers/message-handlers/base-handler.js.map +1 -0
- package/dist/handlers/message-handlers/challenge-handler.d.ts +73 -0
- package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/challenge-handler.js +47 -0
- package/dist/handlers/message-handlers/challenge-handler.js.map +1 -0
- package/dist/handlers/message-handlers/error-message-handler.d.ts +76 -0
- package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/error-message-handler.js +29 -0
- package/dist/handlers/message-handlers/error-message-handler.js.map +1 -0
- package/dist/handlers/message-handlers/index.d.ts +28 -0
- package/dist/handlers/message-handlers/index.d.ts.map +1 -0
- package/dist/handlers/message-handlers/index.js +100 -0
- package/dist/handlers/message-handlers/index.js.map +1 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +122 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.js +30 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts +104 -0
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/ping-pong-handler.js +36 -0
- package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -0
- package/dist/handlers/message-handlers/regular-message-handler.d.ts +56 -0
- package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/regular-message-handler.js +59 -0
- package/dist/handlers/message-handlers/regular-message-handler.js.map +1 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +81 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.js +48 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/task-response-handler.d.ts +14 -0
- package/dist/handlers/message-handlers/task-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/task-response-handler.js +44 -0
- package/dist/handlers/message-handlers/task-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/types.d.ts +51 -0
- package/dist/handlers/message-handlers/types.d.ts.map +1 -0
- package/dist/handlers/message-handlers/types.js +7 -0
- package/dist/handlers/message-handlers/types.js.map +1 -0
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +81 -0
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/unsubscribe-response-handler.js +48 -0
- package/dist/handlers/message-handlers/unsubscribe-response-handler.js.map +1 -0
- package/dist/handlers/webhook-handler.d.ts +202 -0
- package/dist/handlers/webhook-handler.d.ts.map +1 -0
- package/dist/handlers/webhook-handler.js +511 -0
- package/dist/handlers/webhook-handler.js.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +217 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/agent-registry.d.ts +173 -0
- package/dist/managers/agent-registry.d.ts.map +1 -0
- package/dist/managers/agent-registry.js +310 -0
- package/dist/managers/agent-registry.js.map +1 -0
- package/dist/managers/connection-manager.d.ts +134 -0
- package/dist/managers/connection-manager.d.ts.map +1 -0
- package/dist/managers/connection-manager.js +176 -0
- package/dist/managers/connection-manager.js.map +1 -0
- package/dist/managers/index.d.ts +9 -0
- package/dist/managers/index.d.ts.map +1 -0
- package/dist/managers/index.js +16 -0
- package/dist/managers/index.js.map +1 -0
- package/dist/managers/message-router.d.ts +112 -0
- package/dist/managers/message-router.d.ts.map +1 -0
- package/dist/managers/message-router.js +260 -0
- package/dist/managers/message-router.js.map +1 -0
- package/dist/managers/room-manager.d.ts +165 -0
- package/dist/managers/room-manager.d.ts.map +1 -0
- package/dist/managers/room-manager.js +227 -0
- package/dist/managers/room-manager.js.map +1 -0
- package/dist/teneo-sdk.d.ts +703 -0
- package/dist/teneo-sdk.d.ts.map +1 -0
- package/dist/teneo-sdk.js +907 -0
- package/dist/teneo-sdk.js.map +1 -0
- package/dist/types/config.d.ts +1047 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +720 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/error-codes.d.ts +29 -0
- package/dist/types/error-codes.d.ts.map +1 -0
- package/dist/types/error-codes.js +41 -0
- package/dist/types/error-codes.js.map +1 -0
- package/dist/types/events.d.ts +616 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +261 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/health.d.ts +40 -0
- package/dist/types/health.d.ts.map +1 -0
- package/dist/types/health.js +6 -0
- package/dist/types/health.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +123 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/messages.d.ts +3734 -0
- package/dist/types/messages.d.ts.map +1 -0
- package/dist/types/messages.js +482 -0
- package/dist/types/messages.js.map +1 -0
- package/dist/types/validation.d.ts +81 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +115 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/utils/bounded-queue.d.ts +127 -0
- package/dist/utils/bounded-queue.d.ts.map +1 -0
- package/dist/utils/bounded-queue.js +181 -0
- package/dist/utils/bounded-queue.js.map +1 -0
- package/dist/utils/circuit-breaker.d.ts +141 -0
- package/dist/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/utils/circuit-breaker.js +215 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/dist/utils/deduplication-cache.d.ts +110 -0
- package/dist/utils/deduplication-cache.d.ts.map +1 -0
- package/dist/utils/deduplication-cache.js +177 -0
- package/dist/utils/deduplication-cache.js.map +1 -0
- package/dist/utils/event-waiter.d.ts +101 -0
- package/dist/utils/event-waiter.d.ts.map +1 -0
- package/dist/utils/event-waiter.js +118 -0
- package/dist/utils/event-waiter.js.map +1 -0
- package/dist/utils/index.d.ts +51 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +72 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +22 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +91 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +122 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +190 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/retry-policy.d.ts +191 -0
- package/dist/utils/retry-policy.d.ts.map +1 -0
- package/dist/utils/retry-policy.js +225 -0
- package/dist/utils/retry-policy.js.map +1 -0
- package/dist/utils/secure-private-key.d.ts +113 -0
- package/dist/utils/secure-private-key.d.ts.map +1 -0
- package/dist/utils/secure-private-key.js +188 -0
- package/dist/utils/secure-private-key.js.map +1 -0
- package/dist/utils/signature-verifier.d.ts +143 -0
- package/dist/utils/signature-verifier.d.ts.map +1 -0
- package/dist/utils/signature-verifier.js +238 -0
- package/dist/utils/signature-verifier.js.map +1 -0
- package/dist/utils/ssrf-validator.d.ts +36 -0
- package/dist/utils/ssrf-validator.d.ts.map +1 -0
- package/dist/utils/ssrf-validator.js +195 -0
- package/dist/utils/ssrf-validator.js.map +1 -0
- package/examples/.env.example +17 -0
- package/examples/basic-usage.ts +211 -0
- package/examples/production-dashboard/.env.example +153 -0
- package/examples/production-dashboard/package.json +39 -0
- package/examples/production-dashboard/public/dashboard.html +642 -0
- package/examples/production-dashboard/server.ts +753 -0
- package/examples/webhook-integration.ts +239 -0
- package/examples/x-influencer-battle-redesign.html +1065 -0
- package/examples/x-influencer-battle-server.ts +217 -0
- package/examples/x-influencer-battle.html +787 -0
- package/package.json +65 -0
- package/src/constants.ts +43 -0
- package/src/core/websocket-client.test.ts +512 -0
- package/src/core/websocket-client.ts +1056 -0
- package/src/formatters/response-formatter.test.ts +571 -0
- package/src/formatters/response-formatter.ts +677 -0
- package/src/handlers/message-handler-registry.ts +239 -0
- package/src/handlers/message-handlers/agent-selected-handler.ts +40 -0
- package/src/handlers/message-handlers/agents-list-handler.ts +26 -0
- package/src/handlers/message-handlers/auth-error-handler.ts +31 -0
- package/src/handlers/message-handlers/auth-message-handler.ts +66 -0
- package/src/handlers/message-handlers/auth-required-handler.ts +23 -0
- package/src/handlers/message-handlers/auth-success-handler.ts +57 -0
- package/src/handlers/message-handlers/base-handler.ts +101 -0
- package/src/handlers/message-handlers/challenge-handler.ts +57 -0
- package/src/handlers/message-handlers/error-message-handler.ts +27 -0
- package/src/handlers/message-handlers/index.ts +77 -0
- package/src/handlers/message-handlers/list-rooms-response-handler.ts +28 -0
- package/src/handlers/message-handlers/ping-pong-handler.ts +30 -0
- package/src/handlers/message-handlers/regular-message-handler.ts +65 -0
- package/src/handlers/message-handlers/subscribe-response-handler.ts +47 -0
- package/src/handlers/message-handlers/task-response-handler.ts +45 -0
- package/src/handlers/message-handlers/types.ts +77 -0
- package/src/handlers/message-handlers/unsubscribe-response-handler.ts +47 -0
- package/src/handlers/webhook-handler.test.ts +789 -0
- package/src/handlers/webhook-handler.ts +576 -0
- package/src/index.ts +269 -0
- package/src/managers/agent-registry.test.ts +466 -0
- package/src/managers/agent-registry.ts +347 -0
- package/src/managers/connection-manager.ts +195 -0
- package/src/managers/index.ts +9 -0
- package/src/managers/message-router.ts +349 -0
- package/src/managers/room-manager.ts +248 -0
- package/src/teneo-sdk.ts +1022 -0
- package/src/types/config.test.ts +325 -0
- package/src/types/config.ts +799 -0
- package/src/types/error-codes.ts +44 -0
- package/src/types/events.test.ts +302 -0
- package/src/types/events.ts +382 -0
- package/src/types/health.ts +46 -0
- package/src/types/index.ts +199 -0
- package/src/types/messages.test.ts +660 -0
- package/src/types/messages.ts +570 -0
- package/src/types/validation.ts +123 -0
- package/src/utils/bounded-queue.test.ts +356 -0
- package/src/utils/bounded-queue.ts +205 -0
- package/src/utils/circuit-breaker.test.ts +394 -0
- package/src/utils/circuit-breaker.ts +262 -0
- package/src/utils/deduplication-cache.test.ts +380 -0
- package/src/utils/deduplication-cache.ts +198 -0
- package/src/utils/event-waiter.test.ts +381 -0
- package/src/utils/event-waiter.ts +172 -0
- package/src/utils/index.ts +74 -0
- package/src/utils/logger.ts +87 -0
- package/src/utils/rate-limiter.test.ts +341 -0
- package/src/utils/rate-limiter.ts +211 -0
- package/src/utils/retry-policy.test.ts +558 -0
- package/src/utils/retry-policy.ts +272 -0
- package/src/utils/secure-private-key.test.ts +356 -0
- package/src/utils/secure-private-key.ts +205 -0
- package/src/utils/signature-verifier.test.ts +464 -0
- package/src/utils/signature-verifier.ts +298 -0
- package/src/utils/ssrf-validator.test.ts +372 -0
- package/src/utils/ssrf-validator.ts +224 -0
- package/tests/integration/real-server.test.ts +740 -0
- package/tests/integration/websocket.test.ts +381 -0
- package/tests/integration-setup.ts +16 -0
- package/tests/setup.ts +34 -0
- package/tsconfig.json +32 -0
- package/vitest.config.ts +42 -0
- package/vitest.integration.config.ts +23 -0
package/src/teneo-sdk.ts
ADDED
|
@@ -0,0 +1,1022 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Teneo Protocol SDK class
|
|
3
|
+
* Provides a unified interface for external platforms to interact with Teneo agents
|
|
4
|
+
* Uses manager classes to follow Single Responsibility Principle
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { EventEmitter } from "eventemitter3";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import {
|
|
10
|
+
SDKConfig,
|
|
11
|
+
PartialSDKConfig,
|
|
12
|
+
PartialSDKConfigSchema,
|
|
13
|
+
SDKConfigBuilder,
|
|
14
|
+
Agent,
|
|
15
|
+
Room,
|
|
16
|
+
RoomInfo,
|
|
17
|
+
Logger,
|
|
18
|
+
validateConfig,
|
|
19
|
+
DEFAULT_CONFIG,
|
|
20
|
+
ResponseFormatSchema,
|
|
21
|
+
type HealthStatus
|
|
22
|
+
} from "./types";
|
|
23
|
+
import { SDKEvents, SDKError } from "./types/events";
|
|
24
|
+
import { ErrorCode } from "./types/error-codes";
|
|
25
|
+
import { WebSocketClient } from "./core/websocket-client";
|
|
26
|
+
import { WebhookHandler } from "./handlers/webhook-handler";
|
|
27
|
+
import {
|
|
28
|
+
ResponseFormatter,
|
|
29
|
+
FormattedResponse,
|
|
30
|
+
ResponseFormatOptions
|
|
31
|
+
} from "./formatters/response-formatter";
|
|
32
|
+
import {
|
|
33
|
+
ConnectionManager,
|
|
34
|
+
RoomManager,
|
|
35
|
+
AgentRegistry,
|
|
36
|
+
MessageRouter,
|
|
37
|
+
SendMessageOptions,
|
|
38
|
+
AgentCommand
|
|
39
|
+
} from "./managers";
|
|
40
|
+
import { createPinoLogger } from "./utils/logger";
|
|
41
|
+
import { RoomIdSchema, AgentIdSchema, AgentCommandContentSchema } from "./types/validation";
|
|
42
|
+
|
|
43
|
+
// Re-export types for external use
|
|
44
|
+
export type { SendMessageOptions, AgentCommand };
|
|
45
|
+
|
|
46
|
+
// Zod schemas for SDK-specific interfaces
|
|
47
|
+
export const SendMessageOptionsSchema = z.object({
|
|
48
|
+
room: RoomIdSchema.optional(),
|
|
49
|
+
from: z.string().optional(),
|
|
50
|
+
waitForResponse: z.boolean().optional(),
|
|
51
|
+
timeout: z.number().min(1000).max(300000).optional(),
|
|
52
|
+
format: z.union([ResponseFormatSchema, z.literal("raw"), z.literal("humanized")]).optional()
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export const AgentCommandSchema = z.object({
|
|
56
|
+
agent: AgentIdSchema,
|
|
57
|
+
command: AgentCommandContentSchema,
|
|
58
|
+
room: RoomIdSchema.optional()
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
62
|
+
private config: SDKConfig;
|
|
63
|
+
private readonly logger: Logger;
|
|
64
|
+
private isDestroyed = false;
|
|
65
|
+
|
|
66
|
+
// Core components
|
|
67
|
+
private readonly wsClient: WebSocketClient;
|
|
68
|
+
private readonly webhookHandler: WebhookHandler;
|
|
69
|
+
private readonly responseFormatter: ResponseFormatter;
|
|
70
|
+
|
|
71
|
+
// Managers
|
|
72
|
+
private readonly connection: ConnectionManager;
|
|
73
|
+
private readonly rooms: RoomManager;
|
|
74
|
+
private readonly agents: AgentRegistry;
|
|
75
|
+
private readonly messages: MessageRouter;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a new instance of the Teneo Protocol SDK.
|
|
79
|
+
* Initializes all core components, managers, and validates the provided configuration.
|
|
80
|
+
* The SDK handles WebSocket connections, authentication, message routing, and webhook delivery.
|
|
81
|
+
*
|
|
82
|
+
* @param config - Partial SDK configuration object (only wsUrl is required)
|
|
83
|
+
* @param config.wsUrl - WebSocket URL to connect to (e.g., 'wss://teneo.example.com')
|
|
84
|
+
* @param config.privateKey - Optional Ethereum private key for wallet-based authentication
|
|
85
|
+
* @param config.walletAddress - Optional wallet address (derived from privateKey if not provided)
|
|
86
|
+
* @param config.autoJoinRooms - Optional array of room IDs to subscribe to automatically on connection
|
|
87
|
+
* @param config.webhookUrl - Optional webhook URL for receiving event notifications
|
|
88
|
+
* @param config.reconnect - Enable automatic reconnection (default: true)
|
|
89
|
+
* @param config.logLevel - Logging level: 'debug', 'info', 'warn', 'error', 'silent' (default: 'info')
|
|
90
|
+
* @param config.responseFormat - Response format: 'raw', 'humanized', 'both' (default: 'humanized')
|
|
91
|
+
*
|
|
92
|
+
* @throws {SDKError} If configuration is invalid (ErrorCode.INVALID_CONFIG)
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* // Minimal configuration
|
|
97
|
+
* const sdk = new TeneoSDK({
|
|
98
|
+
* wsUrl: 'wss://teneo.example.com',
|
|
99
|
+
* privateKey: '0x...'
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* // Full configuration
|
|
103
|
+
* const sdk = new TeneoSDK({
|
|
104
|
+
* wsUrl: 'wss://teneo.example.com',
|
|
105
|
+
* privateKey: '0x...',
|
|
106
|
+
* autoJoinRooms: ['general', 'announcements'],
|
|
107
|
+
* webhookUrl: 'https://api.example.com/webhooks',
|
|
108
|
+
* logLevel: 'debug',
|
|
109
|
+
* responseFormat: 'both',
|
|
110
|
+
* reconnect: true,
|
|
111
|
+
* maxReconnectAttempts: 10
|
|
112
|
+
* });
|
|
113
|
+
*
|
|
114
|
+
* // Using builder pattern (recommended for complex configs)
|
|
115
|
+
* const sdk = TeneoSDK.builder()
|
|
116
|
+
* .wsUrl('wss://teneo.example.com')
|
|
117
|
+
* .privateKey('0x...')
|
|
118
|
+
* .withAutoJoinRooms(['general'])
|
|
119
|
+
* .build();
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @see {@link SDKConfigBuilder} for fluent configuration API
|
|
123
|
+
* @see {@link TeneoSDK.builder} for creating a configuration builder
|
|
124
|
+
*/
|
|
125
|
+
constructor(config: PartialSDKConfig) {
|
|
126
|
+
super();
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
// Validate partial config first
|
|
130
|
+
const partialConfig = PartialSDKConfigSchema.parse(config);
|
|
131
|
+
|
|
132
|
+
// Merge with defaults
|
|
133
|
+
const fullConfig = { ...DEFAULT_CONFIG, ...partialConfig };
|
|
134
|
+
|
|
135
|
+
// Validate full configuration
|
|
136
|
+
this.config = validateConfig(fullConfig);
|
|
137
|
+
|
|
138
|
+
// Initialize logger
|
|
139
|
+
this.logger = this.config.logger ?? this.createDefaultLogger();
|
|
140
|
+
|
|
141
|
+
// Initialize core components
|
|
142
|
+
this.wsClient = new WebSocketClient(this.config);
|
|
143
|
+
this.webhookHandler = new WebhookHandler(this.config, this.logger);
|
|
144
|
+
this.responseFormatter = new ResponseFormatter({
|
|
145
|
+
format: this.config.responseFormat ?? "humanized",
|
|
146
|
+
includeMetadata: this.config.includeMetadata ?? false
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Initialize managers
|
|
150
|
+
this.connection = new ConnectionManager(this.wsClient, this.logger);
|
|
151
|
+
this.rooms = new RoomManager(this.wsClient, this.logger);
|
|
152
|
+
this.wsClient.setRoomManager(this.rooms); // Enable subscription tracking in handlers
|
|
153
|
+
this.agents = new AgentRegistry(this.logger);
|
|
154
|
+
this.messages = new MessageRouter(
|
|
155
|
+
this.wsClient,
|
|
156
|
+
this.webhookHandler,
|
|
157
|
+
this.responseFormatter,
|
|
158
|
+
this.logger,
|
|
159
|
+
{
|
|
160
|
+
messageTimeout: this.config.messageTimeout,
|
|
161
|
+
responseFormat: this.config.responseFormat
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
// Set up event forwarding
|
|
166
|
+
this.setupEventForwarding();
|
|
167
|
+
|
|
168
|
+
this.logger.info("TeneoSDK initialized", { wsUrl: this.config.wsUrl });
|
|
169
|
+
} catch (error) {
|
|
170
|
+
if (error instanceof z.ZodError) {
|
|
171
|
+
throw new SDKError("Invalid SDK configuration", ErrorCode.INVALID_CONFIG, error, false);
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Establishes a connection to the Teneo network via WebSocket.
|
|
179
|
+
* Handles authentication automatically and joins any configured auto-join rooms.
|
|
180
|
+
* Emits 'connection:open', 'auth:success', and 'ready' events on successful connection.
|
|
181
|
+
*
|
|
182
|
+
* @returns Promise that resolves when connection and authentication are complete
|
|
183
|
+
* @throws {SDKError} If the SDK has been destroyed (ErrorCode.SDK_DESTROYED)
|
|
184
|
+
* @throws {ConnectionError} If WebSocket connection fails
|
|
185
|
+
* @throws {AuthenticationError} If authentication fails
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const sdk = new TeneoSDK({ wsUrl: 'wss://example.com', privateKey: '0x...' });
|
|
190
|
+
* await sdk.connect();
|
|
191
|
+
* console.log('Connected to Teneo network');
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
public async connect(): Promise<void> {
|
|
195
|
+
if (this.isDestroyed) {
|
|
196
|
+
throw new SDKError("SDK has been destroyed", ErrorCode.SDK_DESTROYED, null, false);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
this.logger.info("Connecting to Teneo network");
|
|
201
|
+
await this.connection.connect();
|
|
202
|
+
|
|
203
|
+
// Auto-join rooms if configured
|
|
204
|
+
if (this.config.autoJoinRooms && this.config.autoJoinRooms.length > 0) {
|
|
205
|
+
for (const room of this.config.autoJoinRooms) {
|
|
206
|
+
await this.rooms.subscribeToRoom(room);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.logger.info("Successfully connected to Teneo network");
|
|
211
|
+
} catch (error) {
|
|
212
|
+
this.logger.error("Failed to connect to Teneo network", error);
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Disconnects from the Teneo network and cleans up all active connections.
|
|
219
|
+
* Clears all timers, pending messages, and stops automatic reconnection attempts.
|
|
220
|
+
* Emits 'disconnect' event after disconnection is complete.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* sdk.disconnect();
|
|
225
|
+
* console.log('Disconnected from Teneo network');
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
public disconnect(): void {
|
|
229
|
+
this.logger.info("Disconnecting from Teneo network");
|
|
230
|
+
this.connection.disconnect();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Sends a message to agents via the coordinator, which intelligently selects
|
|
235
|
+
* the most appropriate agent based on the message content and agent capabilities.
|
|
236
|
+
* Can optionally wait for and return the agent's response.
|
|
237
|
+
*
|
|
238
|
+
* @param content - The message content to send to agents
|
|
239
|
+
* @param options - Optional message configuration
|
|
240
|
+
* @param options.room - Room to send message to (defaults to configured default room)
|
|
241
|
+
* @param options.from - Sender address (defaults to authenticated wallet address)
|
|
242
|
+
* @param options.waitForResponse - Whether to wait for agent response (default: false)
|
|
243
|
+
* @param options.timeout - Response timeout in milliseconds (default: 60000, max: 300000)
|
|
244
|
+
* @param options.format - Response format: 'raw', 'humanized', or 'both'
|
|
245
|
+
* @returns Promise that resolves to FormattedResponse if waitForResponse is true, void otherwise
|
|
246
|
+
* @throws {SDKError} If not connected to the network (ErrorCode.NOT_CONNECTED)
|
|
247
|
+
* @throws {ValidationError} If content is empty or options are invalid
|
|
248
|
+
* @throws {TimeoutError} If waitForResponse is true and timeout is exceeded
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```typescript
|
|
252
|
+
* // Fire-and-forget message
|
|
253
|
+
* await sdk.sendMessage('What is the weather today?');
|
|
254
|
+
*
|
|
255
|
+
* // Wait for response
|
|
256
|
+
* const response = await sdk.sendMessage('What is 2+2?', {
|
|
257
|
+
* waitForResponse: true,
|
|
258
|
+
* timeout: 30000
|
|
259
|
+
* });
|
|
260
|
+
* console.log(response.humanized); // Agent's response in human-readable format
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
public async sendMessage(
|
|
264
|
+
content: string,
|
|
265
|
+
options: SendMessageOptions
|
|
266
|
+
): Promise<FormattedResponse | void> {
|
|
267
|
+
return this.messages.sendMessage(content, options);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Sends a direct command to a specific agent, bypassing the coordinator.
|
|
272
|
+
* Use this when you know exactly which agent should handle the request.
|
|
273
|
+
* The command is formatted as "@agentName command" internally.
|
|
274
|
+
*
|
|
275
|
+
* @param command - The direct agent command configuration
|
|
276
|
+
* @param command.agent - The agent ID or name to send the command to
|
|
277
|
+
* @param command.command - The command text to send to the agent
|
|
278
|
+
* @param command.room - Room to send command to (defaults to configured default room)
|
|
279
|
+
* @returns Promise that resolves when the command is sent
|
|
280
|
+
* @throws {SDKError} If not connected to the network (ErrorCode.NOT_CONNECTED)
|
|
281
|
+
* @throws {ValidationError} If agent or command are empty, or room is not configured
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* // Send command to specific agent
|
|
286
|
+
* await sdk.sendDirectCommand({
|
|
287
|
+
* agent: 'weather-agent',
|
|
288
|
+
* command: 'Get forecast for New York',
|
|
289
|
+
* room: 'general'
|
|
290
|
+
* });
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
public async sendDirectCommand(command: AgentCommand): Promise<FormattedResponse | void> {
|
|
294
|
+
return this.messages.sendDirectCommand(command);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Subscribes to a specified room in the Teneo network.
|
|
299
|
+
* Agents in the room will be able to see and respond to your messages.
|
|
300
|
+
* Emits 'room:subscribed' event when successfully subscribed.
|
|
301
|
+
*
|
|
302
|
+
* @param roomId - The ID of the room to subscribe to
|
|
303
|
+
* @returns Promise that resolves when the room has been subscribed
|
|
304
|
+
* @throws {SDKError} If not connected to the network (ErrorCode.NOT_CONNECTED)
|
|
305
|
+
* @throws {ValidationError} If roomId is empty or invalid
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```typescript
|
|
309
|
+
* await sdk.subscribeToRoom('general');
|
|
310
|
+
* console.log('Subscribed to general room');
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
public async subscribeToRoom(roomId: string): Promise<void> {
|
|
314
|
+
return this.rooms.subscribeToRoom(roomId);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Unsubscribes from a specified room in the Teneo network.
|
|
319
|
+
* You will no longer receive messages from agents in this room.
|
|
320
|
+
* Emits 'room:unsubscribed' event when successfully unsubscribed.
|
|
321
|
+
*
|
|
322
|
+
* @param roomId - The ID of the room to unsubscribe from
|
|
323
|
+
* @returns Promise that resolves when the room has been unsubscribed
|
|
324
|
+
* @throws {SDKError} If not connected to the network (ErrorCode.NOT_CONNECTED)
|
|
325
|
+
* @throws {ValidationError} If roomId is empty or invalid
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```typescript
|
|
329
|
+
* await sdk.unsubscribeFromRoom('general');
|
|
330
|
+
* console.log('Unsubscribed from general room');
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
public async unsubscribeFromRoom(roomId: string): Promise<void> {
|
|
334
|
+
return this.rooms.unsubscribeFromRoom(roomId);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Lists all rooms available to the user.
|
|
339
|
+
* Fetches room list from the server including owned and shared rooms.
|
|
340
|
+
* Emits 'room:list' event when the list is received.
|
|
341
|
+
*
|
|
342
|
+
* @returns Promise that resolves to array of room information
|
|
343
|
+
* @throws {SDKError} If not connected to the network (ErrorCode.NOT_CONNECTED)
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* const rooms = await sdk.listRooms();
|
|
348
|
+
* rooms.forEach(room => {
|
|
349
|
+
* console.log(`${room.name} (${room.is_public ? 'public' : 'private'})`);
|
|
350
|
+
* console.log(`Owner: ${room.is_owner}`);
|
|
351
|
+
* });
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
public async listRooms(): Promise<RoomInfo[]> {
|
|
355
|
+
return this.rooms.listRooms();
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Gets all rooms currently subscribed to.
|
|
360
|
+
* Returns array of room IDs that you're actively listening to for messages.
|
|
361
|
+
*
|
|
362
|
+
* @returns Array of subscribed room IDs
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* const rooms = sdk.getSubscribedRooms();
|
|
367
|
+
* console.log(`Subscribed to ${rooms.length} rooms:`, rooms);
|
|
368
|
+
* // Example output: Subscribed to 3 rooms: ['general', 'support', 'trading']
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
public getSubscribedRooms(): string[] {
|
|
372
|
+
return this.rooms.getSubscribedRooms();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Gets a list of all available agents in the Teneo network.
|
|
377
|
+
* The list is automatically updated when new agents join or leave.
|
|
378
|
+
* Returns a read-only array to prevent external modification.
|
|
379
|
+
*
|
|
380
|
+
* @returns Read-only array of all available agents
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```typescript
|
|
384
|
+
* const agents = sdk.getAgents();
|
|
385
|
+
* console.log(`Found ${agents.length} agents:`);
|
|
386
|
+
* agents.forEach(agent => {
|
|
387
|
+
* console.log(`- ${agent.name}: ${agent.description}`);
|
|
388
|
+
* });
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
391
|
+
public getAgents(): ReadonlyArray<Agent> {
|
|
392
|
+
return this.agents.getAgents();
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Gets a specific agent by its unique ID.
|
|
397
|
+
* Returns undefined if no agent with the specified ID exists.
|
|
398
|
+
*
|
|
399
|
+
* @param agentId - The unique identifier of the agent to retrieve
|
|
400
|
+
* @returns The agent object if found, undefined otherwise
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* const agent = sdk.getAgent('weather-agent-001');
|
|
405
|
+
* if (agent) {
|
|
406
|
+
* console.log(`Found agent: ${agent.name}`);
|
|
407
|
+
* console.log(`Status: ${agent.status}`);
|
|
408
|
+
* } else {
|
|
409
|
+
* console.log('Agent not found');
|
|
410
|
+
* }
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
public getAgent(agentId: string): Agent | undefined {
|
|
414
|
+
return this.agents.getAgent(agentId);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Finds all agents that have a specific capability using O(1) indexed lookup (PERF-3).
|
|
419
|
+
* Much faster than filtering through all agents manually.
|
|
420
|
+
* Uses capability index for constant-time lookups regardless of agent count.
|
|
421
|
+
*
|
|
422
|
+
* @param capability - The capability name to search for (case-insensitive)
|
|
423
|
+
* @returns Read-only array of agents with the specified capability
|
|
424
|
+
* @throws {ValidationError} If capability name is invalid
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```typescript
|
|
428
|
+
* // Find all weather-capable agents
|
|
429
|
+
* const weatherAgents = sdk.findAgentsByCapability('weather-forecast');
|
|
430
|
+
* console.log(`Found ${weatherAgents.length} weather agents`);
|
|
431
|
+
*
|
|
432
|
+
* weatherAgents.forEach(agent => {
|
|
433
|
+
* console.log(`- ${agent.name}: ${agent.description}`);
|
|
434
|
+
* });
|
|
435
|
+
* ```
|
|
436
|
+
*/
|
|
437
|
+
public findAgentsByCapability(capability: string): ReadonlyArray<Agent> {
|
|
438
|
+
return this.agents.findByCapability(capability);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Finds agents by name using O(k) token-based search (PERF-3).
|
|
443
|
+
* Supports partial matching - searches for tokens within agent names.
|
|
444
|
+
* Tokenizes both the search query and agent names for flexible matching.
|
|
445
|
+
*
|
|
446
|
+
* @param name - Name or partial name to search for (case-insensitive)
|
|
447
|
+
* @returns Read-only array of agents matching the search
|
|
448
|
+
* @throws {ValidationError} If name is invalid
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```typescript
|
|
452
|
+
* // Find all agents with "weather" in their name
|
|
453
|
+
* const agents = sdk.findAgentsByName('weather');
|
|
454
|
+
* // Matches: "Weather Agent", "Weather Forecast Bot", "Advanced Weather API", etc.
|
|
455
|
+
*
|
|
456
|
+
* console.log(`Found ${agents.length} agents matching 'weather'`);
|
|
457
|
+
* ```
|
|
458
|
+
*/
|
|
459
|
+
public findAgentsByName(name: string): ReadonlyArray<Agent> {
|
|
460
|
+
return this.agents.findByName(name);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Finds all agents with a specific status using O(1) indexed lookup (PERF-3).
|
|
465
|
+
* Uses status index for constant-time lookups regardless of agent count.
|
|
466
|
+
*
|
|
467
|
+
* @param status - Agent status: 'online' or 'offline' (case-insensitive)
|
|
468
|
+
* @returns Read-only array of agents with the specified status
|
|
469
|
+
* @throws {ValidationError} If status is invalid
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```typescript
|
|
473
|
+
* // Get all online agents
|
|
474
|
+
* const onlineAgents = sdk.findAgentsByStatus('online');
|
|
475
|
+
* console.log(`${onlineAgents.length} agents are currently online`);
|
|
476
|
+
*
|
|
477
|
+
* // Get offline agents
|
|
478
|
+
* const offlineAgents = sdk.findAgentsByStatus('offline');
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
481
|
+
public findAgentsByStatus(status: string): ReadonlyArray<Agent> {
|
|
482
|
+
return this.agents.findByStatus(status);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Gets a list of all available rooms in the Teneo network.
|
|
487
|
+
* Includes rooms you have access to based on your authentication.
|
|
488
|
+
* Returns a read-only array to prevent external modification.
|
|
489
|
+
*
|
|
490
|
+
* @returns Read-only array of all available rooms
|
|
491
|
+
*
|
|
492
|
+
* @example
|
|
493
|
+
* ```typescript
|
|
494
|
+
* const rooms = sdk.getRooms();
|
|
495
|
+
* console.log(`Available rooms: ${rooms.length}`);
|
|
496
|
+
* rooms.forEach(room => {
|
|
497
|
+
* console.log(`- ${room.id} (${room.name})`);
|
|
498
|
+
* });
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
public getRooms(): ReadonlyArray<Room> {
|
|
502
|
+
return this.rooms.getRooms();
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Gets a specific room by its unique ID.
|
|
507
|
+
* Returns undefined if no room with the specified ID exists or if you don't have access.
|
|
508
|
+
*
|
|
509
|
+
* @param roomId - The unique identifier of the room to retrieve
|
|
510
|
+
* @returns The room object if found, undefined otherwise
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* ```typescript
|
|
514
|
+
* const room = sdk.getRoom('general');
|
|
515
|
+
* if (room) {
|
|
516
|
+
* console.log(`Found room: ${room.name}`);
|
|
517
|
+
* console.log(`Members: ${room.members?.length ?? 0}`);
|
|
518
|
+
* } else {
|
|
519
|
+
* console.log('Room not found or no access');
|
|
520
|
+
* }
|
|
521
|
+
* ```
|
|
522
|
+
*/
|
|
523
|
+
public getRoom(roomId: string): Room | undefined {
|
|
524
|
+
return this.rooms.getRoom(roomId);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Configures webhook URL and headers for receiving real-time event notifications.
|
|
529
|
+
* Webhooks allow you to receive events at your server endpoint via HTTP POST requests.
|
|
530
|
+
* Events include messages, agent responses, errors, and connection state changes.
|
|
531
|
+
*
|
|
532
|
+
* @param url - The webhook URL endpoint to receive events (must be HTTPS unless localhost)
|
|
533
|
+
* @param headers - Optional custom HTTP headers to include with webhook requests
|
|
534
|
+
* @throws {WebhookError} If URL is invalid or insecure (non-HTTPS and not localhost)
|
|
535
|
+
*
|
|
536
|
+
* @example
|
|
537
|
+
* ```typescript
|
|
538
|
+
* sdk.configureWebhook('https://api.example.com/webhooks/teneo', {
|
|
539
|
+
* 'Authorization': 'Bearer your-token',
|
|
540
|
+
* 'X-Custom-Header': 'value'
|
|
541
|
+
* });
|
|
542
|
+
*
|
|
543
|
+
* // Listen for webhook events
|
|
544
|
+
* sdk.on('webhook:sent', (payload, url) => {
|
|
545
|
+
* console.log('Webhook sent:', payload.event);
|
|
546
|
+
* });
|
|
547
|
+
* ```
|
|
548
|
+
*/
|
|
549
|
+
public configureWebhook(url: string, headers?: Record<string, string>): void {
|
|
550
|
+
this.webhookHandler.configure({
|
|
551
|
+
url,
|
|
552
|
+
headers,
|
|
553
|
+
retries: this.config.webhookRetries,
|
|
554
|
+
timeout: this.config.webhookTimeout
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Gets the current WebSocket connection state including connection status,
|
|
560
|
+
* authentication status, reconnection attempts, and timestamps.
|
|
561
|
+
*
|
|
562
|
+
* @returns Object containing detailed connection state information
|
|
563
|
+
* @returns {boolean} returns.connected - Whether WebSocket is currently connected
|
|
564
|
+
* @returns {boolean} returns.authenticated - Whether authentication is complete
|
|
565
|
+
* @returns {boolean} returns.reconnecting - Whether currently attempting to reconnect
|
|
566
|
+
* @returns {number} returns.reconnectAttempts - Number of reconnection attempts made
|
|
567
|
+
* @returns {Date} returns.lastConnectedAt - Timestamp of last successful connection
|
|
568
|
+
* @returns {Date} returns.lastDisconnectedAt - Timestamp of last disconnection
|
|
569
|
+
* @returns {Error} returns.lastError - Last error that occurred
|
|
570
|
+
*
|
|
571
|
+
* @example
|
|
572
|
+
* ```typescript
|
|
573
|
+
* const state = sdk.getConnectionState();
|
|
574
|
+
* console.log(`Connected: ${state.connected}`);
|
|
575
|
+
* console.log(`Authenticated: ${state.authenticated}`);
|
|
576
|
+
* if (state.reconnecting) {
|
|
577
|
+
* console.log(`Reconnection attempts: ${state.reconnectAttempts}`);
|
|
578
|
+
* }
|
|
579
|
+
* ```
|
|
580
|
+
*/
|
|
581
|
+
public getConnectionState() {
|
|
582
|
+
return this.connection.getConnectionState();
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Gets the current authentication state including wallet address, rooms, and permissions.
|
|
587
|
+
* Updated after successful authentication and includes user profile information.
|
|
588
|
+
*
|
|
589
|
+
* @returns Object containing detailed authentication state information
|
|
590
|
+
* @returns {boolean} returns.authenticated - Whether authentication is complete
|
|
591
|
+
* @returns {string} returns.walletAddress - Authenticated wallet address
|
|
592
|
+
* @returns {string} returns.challenge - Authentication challenge string
|
|
593
|
+
* @returns {string[]} returns.rooms - Array of room IDs the user has access to
|
|
594
|
+
* @returns {Room[]} returns.roomObjects - Full room objects with details
|
|
595
|
+
*
|
|
596
|
+
* @example
|
|
597
|
+
* ```typescript
|
|
598
|
+
* const authState = sdk.getAuthState();
|
|
599
|
+
* if (authState.authenticated) {
|
|
600
|
+
* console.log(`Authenticated as: ${authState.walletAddress}`);
|
|
601
|
+
* console.log(`Access to ${authState.rooms?.length ?? 0} rooms`);
|
|
602
|
+
* } else {
|
|
603
|
+
* console.log('Not authenticated');
|
|
604
|
+
* }
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
public getAuthState() {
|
|
608
|
+
return this.connection.getAuthState();
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Quick check for whether the WebSocket connection is currently active.
|
|
613
|
+
* This is a convenience getter that returns only the connection status.
|
|
614
|
+
* For detailed state information, use getConnectionState().
|
|
615
|
+
*
|
|
616
|
+
* @returns True if connected to the Teneo network, false otherwise
|
|
617
|
+
*
|
|
618
|
+
* @example
|
|
619
|
+
* ```typescript
|
|
620
|
+
* if (sdk.isConnected) {
|
|
621
|
+
* await sdk.sendMessage('Hello!');
|
|
622
|
+
* } else {
|
|
623
|
+
* console.log('Not connected');
|
|
624
|
+
* await sdk.connect();
|
|
625
|
+
* }
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
public get isConnected(): boolean {
|
|
629
|
+
return this.connection.isConnected;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Quick check for whether authentication is complete.
|
|
634
|
+
* This is a convenience getter that returns only the authentication status.
|
|
635
|
+
* For detailed auth information, use getAuthState().
|
|
636
|
+
*
|
|
637
|
+
* @returns True if authenticated with the Teneo network, false otherwise
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* ```typescript
|
|
641
|
+
* if (sdk.isAuthenticated) {
|
|
642
|
+
* console.log('Ready to send messages');
|
|
643
|
+
* } else {
|
|
644
|
+
* console.log('Waiting for authentication...');
|
|
645
|
+
* }
|
|
646
|
+
* ```
|
|
647
|
+
*/
|
|
648
|
+
public get isAuthenticated(): boolean {
|
|
649
|
+
return this.connection.isAuthenticated;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Configures how agent responses are formatted when received.
|
|
654
|
+
* Supports raw JSON, humanized text, or both formats simultaneously.
|
|
655
|
+
* Also controls metadata inclusion and pretty-printing options.
|
|
656
|
+
*
|
|
657
|
+
* @param options - Response formatting configuration options
|
|
658
|
+
* @param options.format - Format type: 'raw' (JSON), 'humanized' (text), or 'both'
|
|
659
|
+
* @param options.includeMetadata - Whether to include metadata in responses (timestamps, agent info, etc.)
|
|
660
|
+
* @param options.includeTimestamps - Whether to include timestamps in formatted output
|
|
661
|
+
* @param options.prettyPrint - Whether to pretty-print JSON output
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* ```typescript
|
|
665
|
+
* // Get both raw JSON and humanized text
|
|
666
|
+
* sdk.setResponseFormat({
|
|
667
|
+
* format: 'both',
|
|
668
|
+
* includeMetadata: true
|
|
669
|
+
* });
|
|
670
|
+
*
|
|
671
|
+
* const response = await sdk.sendMessage('Hello', { waitForResponse: true });
|
|
672
|
+
* console.log(response.humanized); // Human-readable text
|
|
673
|
+
* console.log(response.raw); // Original JSON
|
|
674
|
+
* console.log(response.metadata); // Timestamp, agent info, etc.
|
|
675
|
+
* ```
|
|
676
|
+
*/
|
|
677
|
+
public setResponseFormat(options: ResponseFormatOptions): void {
|
|
678
|
+
// Update formatter with new options
|
|
679
|
+
this.responseFormatter.setFormatOptions(options);
|
|
680
|
+
|
|
681
|
+
// Update config if format is specified
|
|
682
|
+
if (options.format !== undefined) {
|
|
683
|
+
this.config.responseFormat = options.format;
|
|
684
|
+
}
|
|
685
|
+
if (options.includeMetadata !== undefined) {
|
|
686
|
+
this.config.includeMetadata = options.includeMetadata;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Gets the current status of the webhook system including configuration,
|
|
692
|
+
* queue status, and pending/failed webhook deliveries.
|
|
693
|
+
*
|
|
694
|
+
* @returns Object containing webhook status information
|
|
695
|
+
* @returns {boolean} returns.configured - Whether a webhook URL is configured
|
|
696
|
+
* @returns {WebhookConfig} returns.config - Current webhook configuration (URL, headers, retries, etc.)
|
|
697
|
+
* @returns {Object} returns.queue - Webhook delivery queue status
|
|
698
|
+
* @returns {number} returns.queue.pending - Number of webhooks pending delivery
|
|
699
|
+
* @returns {boolean} returns.queue.processing - Whether webhooks are currently being processed
|
|
700
|
+
* @returns {number} returns.queue.failed - Number of failed webhook deliveries in queue
|
|
701
|
+
*
|
|
702
|
+
* @example
|
|
703
|
+
* ```typescript
|
|
704
|
+
* const status = sdk.getWebhookStatus();
|
|
705
|
+
* if (status.configured) {
|
|
706
|
+
* console.log(`Webhook URL: ${status.config.url}`);
|
|
707
|
+
* console.log(`Pending: ${status.queue.pending}`);
|
|
708
|
+
* console.log(`Failed: ${status.queue.failed}`);
|
|
709
|
+
* } else {
|
|
710
|
+
* console.log('Webhook not configured');
|
|
711
|
+
* }
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
public getWebhookStatus() {
|
|
715
|
+
return {
|
|
716
|
+
configured: this.webhookHandler.isConfigured,
|
|
717
|
+
config: this.webhookHandler.getConfig(),
|
|
718
|
+
queue: this.webhookHandler.getQueueStatus()
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Retries all failed webhook deliveries in the queue.
|
|
724
|
+
* Resets attempt counters and immediately attempts to deliver all failed webhooks.
|
|
725
|
+
* Useful for recovering from temporary network issues or webhook endpoint downtime.
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* ```typescript
|
|
729
|
+
* const status = sdk.getWebhookStatus();
|
|
730
|
+
* if (status.queue.failed > 0) {
|
|
731
|
+
* console.log(`Retrying ${status.queue.failed} failed webhooks...`);
|
|
732
|
+
* sdk.retryFailedWebhooks();
|
|
733
|
+
* }
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
public retryFailedWebhooks(): void {
|
|
737
|
+
this.webhookHandler.retryFailed();
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Clears all pending and failed webhooks from the delivery queue.
|
|
742
|
+
* Use this to discard webhooks that are no longer relevant or to recover from queue issues.
|
|
743
|
+
* Warning: This will permanently discard all queued webhook events.
|
|
744
|
+
*
|
|
745
|
+
* @example
|
|
746
|
+
* ```typescript
|
|
747
|
+
* // Clear stale webhooks after reconfiguration
|
|
748
|
+
* sdk.clearWebhookQueue();
|
|
749
|
+
* sdk.configureWebhook('https://api.example.com/new-endpoint');
|
|
750
|
+
* console.log('Webhook queue cleared and reconfigured');
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
public clearWebhookQueue(): void {
|
|
754
|
+
this.webhookHandler.clearQueue();
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Gets comprehensive health status of all SDK components.
|
|
759
|
+
* Useful for monitoring, debugging, and operational dashboards.
|
|
760
|
+
* Returns status of connection, webhooks, rate limiting, agents, and rooms.
|
|
761
|
+
*
|
|
762
|
+
* Overall health status calculation:
|
|
763
|
+
* - healthy: All components operational
|
|
764
|
+
* - degraded: Some components have issues but SDK is functional (e.g., webhook failures, circuit open)
|
|
765
|
+
* - unhealthy: Critical components are not operational (e.g., disconnected, authentication failed)
|
|
766
|
+
*
|
|
767
|
+
* @returns Complete health status object with all component states
|
|
768
|
+
* @returns {string} returns.status - Overall health: 'healthy', 'degraded', or 'unhealthy'
|
|
769
|
+
* @returns {string} returns.timestamp - ISO timestamp of health check
|
|
770
|
+
* @returns {Object} returns.connection - WebSocket connection health
|
|
771
|
+
* @returns {Object} returns.webhook - Webhook delivery health including circuit breaker state
|
|
772
|
+
* @returns {Object} returns.rateLimit - Rate limiter status (if configured)
|
|
773
|
+
* @returns {Object} returns.agents - Agent registry health
|
|
774
|
+
* @returns {Object} returns.rooms - Room management health
|
|
775
|
+
*
|
|
776
|
+
* @example
|
|
777
|
+
* ```typescript
|
|
778
|
+
* const health = sdk.getHealth();
|
|
779
|
+
* console.log(`SDK Status: ${health.status}`);
|
|
780
|
+
* console.log(`Connected: ${health.connection.status}`);
|
|
781
|
+
* console.log(`Agents: ${health.agents.count}`);
|
|
782
|
+
* console.log(`Webhook Circuit: ${health.webhook.circuitState}`);
|
|
783
|
+
*
|
|
784
|
+
* if (health.status !== 'healthy') {
|
|
785
|
+
* console.warn('SDK is degraded or unhealthy');
|
|
786
|
+
* if (!health.connection.authenticated) {
|
|
787
|
+
* console.log('Authentication issue');
|
|
788
|
+
* }
|
|
789
|
+
* if (health.webhook.failed > 0) {
|
|
790
|
+
* console.log(`${health.webhook.failed} failed webhooks`);
|
|
791
|
+
* }
|
|
792
|
+
* }
|
|
793
|
+
* ```
|
|
794
|
+
*/
|
|
795
|
+
public getHealth(): HealthStatus {
|
|
796
|
+
const connectionState = this.connection.getConnectionState();
|
|
797
|
+
const webhookStatus = this.getWebhookStatus();
|
|
798
|
+
const rateLimitStatus = this.wsClient.getRateLimiterStatus();
|
|
799
|
+
|
|
800
|
+
// Determine connection status
|
|
801
|
+
let connectionStatus: "connected" | "disconnected" | "reconnecting";
|
|
802
|
+
if (connectionState.reconnecting) {
|
|
803
|
+
connectionStatus = "reconnecting";
|
|
804
|
+
} else if (connectionState.connected) {
|
|
805
|
+
connectionStatus = "connected";
|
|
806
|
+
} else {
|
|
807
|
+
connectionStatus = "disconnected";
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// Determine webhook health
|
|
811
|
+
let webhookHealth: "healthy" | "degraded" | "unhealthy" = "healthy";
|
|
812
|
+
if (!webhookStatus.configured) {
|
|
813
|
+
// Webhook not configured is not unhealthy
|
|
814
|
+
webhookHealth = "healthy";
|
|
815
|
+
} else if (webhookStatus.queue.circuitState === "OPEN") {
|
|
816
|
+
webhookHealth = "unhealthy";
|
|
817
|
+
} else if (webhookStatus.queue.failed > 0 || webhookStatus.queue.circuitState === "HALF_OPEN") {
|
|
818
|
+
webhookHealth = "degraded";
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// Determine overall health
|
|
822
|
+
let overallStatus: "healthy" | "degraded" | "unhealthy";
|
|
823
|
+
if (!connectionState.connected && !connectionState.reconnecting) {
|
|
824
|
+
overallStatus = "unhealthy";
|
|
825
|
+
} else if (!connectionState.authenticated && connectionState.reconnecting) {
|
|
826
|
+
overallStatus = "degraded";
|
|
827
|
+
} else if (webhookHealth === "unhealthy") {
|
|
828
|
+
overallStatus = "degraded";
|
|
829
|
+
} else if (webhookHealth === "degraded") {
|
|
830
|
+
overallStatus = "degraded";
|
|
831
|
+
} else {
|
|
832
|
+
overallStatus = "healthy";
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
return {
|
|
836
|
+
status: overallStatus,
|
|
837
|
+
timestamp: new Date().toISOString(),
|
|
838
|
+
connection: {
|
|
839
|
+
status: connectionStatus,
|
|
840
|
+
authenticated: connectionState.authenticated,
|
|
841
|
+
reconnectAttempts: connectionState.reconnectAttempts
|
|
842
|
+
},
|
|
843
|
+
webhook: {
|
|
844
|
+
configured: webhookStatus.configured,
|
|
845
|
+
status: webhookHealth,
|
|
846
|
+
pending: webhookStatus.queue.pending,
|
|
847
|
+
failed: webhookStatus.queue.failed,
|
|
848
|
+
circuitState: webhookStatus.queue.circuitState
|
|
849
|
+
},
|
|
850
|
+
rateLimit: rateLimitStatus,
|
|
851
|
+
agents: {
|
|
852
|
+
count: this.agents.getAgents().length
|
|
853
|
+
},
|
|
854
|
+
rooms: {
|
|
855
|
+
count: this.rooms.getRooms().length,
|
|
856
|
+
subscribedRooms: this.rooms.getSubscribedRooms()
|
|
857
|
+
}
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* Destroys the SDK instance and cleans up all resources.
|
|
863
|
+
* Disconnects from the network, clears all managers, removes event listeners,
|
|
864
|
+
* and marks the SDK as destroyed. After calling destroy(), the SDK instance
|
|
865
|
+
* cannot be reused - create a new instance instead.
|
|
866
|
+
* Emits 'destroy' event before completion.
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* ```typescript
|
|
870
|
+
* // Clean up when shutting down
|
|
871
|
+
* sdk.destroy();
|
|
872
|
+
* console.log('SDK destroyed and resources cleaned up');
|
|
873
|
+
*
|
|
874
|
+
* // Create new instance if needed
|
|
875
|
+
* const newSdk = new TeneoSDK(config);
|
|
876
|
+
* ```
|
|
877
|
+
*/
|
|
878
|
+
public destroy(): void {
|
|
879
|
+
if (this.isDestroyed) return;
|
|
880
|
+
|
|
881
|
+
this.logger.info("Destroying TeneoSDK");
|
|
882
|
+
this.isDestroyed = true;
|
|
883
|
+
|
|
884
|
+
// Destroy managers
|
|
885
|
+
this.connection.destroy();
|
|
886
|
+
this.rooms.destroy();
|
|
887
|
+
this.agents.destroy();
|
|
888
|
+
this.messages.destroy();
|
|
889
|
+
|
|
890
|
+
// Destroy other components
|
|
891
|
+
this.webhookHandler.destroy();
|
|
892
|
+
this.removeAllListeners();
|
|
893
|
+
|
|
894
|
+
this.emit("destroy");
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Set up event forwarding from managers
|
|
899
|
+
*/
|
|
900
|
+
private setupEventForwarding(): void {
|
|
901
|
+
// Forward connection events from ConnectionManager
|
|
902
|
+
this.connection.on("connection:open", () => this.emit("connection:open"));
|
|
903
|
+
this.connection.on("connection:close", (code, reason) =>
|
|
904
|
+
this.emit("connection:close", code, reason)
|
|
905
|
+
);
|
|
906
|
+
this.connection.on("connection:error", (error) => this.emit("connection:error", error));
|
|
907
|
+
this.connection.on("connection:reconnecting", (attempt) =>
|
|
908
|
+
this.emit("connection:reconnecting", attempt)
|
|
909
|
+
);
|
|
910
|
+
this.connection.on("connection:reconnected", () => this.emit("connection:reconnected"));
|
|
911
|
+
this.connection.on("connection:state", (state) => this.emit("connection:state", state));
|
|
912
|
+
|
|
913
|
+
// Forward auth events from ConnectionManager
|
|
914
|
+
this.connection.on("auth:challenge", (challenge) => this.emit("auth:challenge", challenge));
|
|
915
|
+
this.connection.on("auth:success", (state) => {
|
|
916
|
+
this.logger.debug("Received auth:success event in SDK", {
|
|
917
|
+
authenticated: state?.authenticated,
|
|
918
|
+
hasRooms: !!state?.roomObjects
|
|
919
|
+
});
|
|
920
|
+
|
|
921
|
+
// Update rooms from auth state
|
|
922
|
+
if (state.roomObjects) {
|
|
923
|
+
this.rooms.updateRoomsFromAuth(state.roomObjects);
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
this.emit("auth:success", state);
|
|
927
|
+
});
|
|
928
|
+
this.connection.on("auth:error", (error) => this.emit("auth:error", error));
|
|
929
|
+
this.connection.on("auth:state", (state) => this.emit("auth:state", state));
|
|
930
|
+
|
|
931
|
+
// Forward message events from MessageRouter
|
|
932
|
+
this.messages.on("message:sent", (message) => this.emit("message:sent", message));
|
|
933
|
+
this.messages.on("message:received", (message) => this.emit("message:received", message));
|
|
934
|
+
this.messages.on("message:error", (error, message) =>
|
|
935
|
+
this.emit("message:error", error, message)
|
|
936
|
+
);
|
|
937
|
+
|
|
938
|
+
// Forward agent events from MessageRouter
|
|
939
|
+
this.messages.on("agent:selected", (data) => this.emit("agent:selected", data));
|
|
940
|
+
this.messages.on("agent:response", (response) => this.emit("agent:response", response));
|
|
941
|
+
|
|
942
|
+
// Forward coordinator events from MessageRouter
|
|
943
|
+
this.messages.on("coordinator:processing", (request) =>
|
|
944
|
+
this.emit("coordinator:processing", request)
|
|
945
|
+
);
|
|
946
|
+
this.messages.on("coordinator:selected", (agentId, reasoning) =>
|
|
947
|
+
this.emit("coordinator:selected", agentId, reasoning)
|
|
948
|
+
);
|
|
949
|
+
this.messages.on("coordinator:error", (error) => this.emit("coordinator:error", error));
|
|
950
|
+
|
|
951
|
+
// Handle agent list updates from WebSocketClient
|
|
952
|
+
this.wsClient.on("agent:list", (agents) => {
|
|
953
|
+
this.agents.updateAgents(agents);
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
// Forward room events from WebSocketClient (emitted by handlers)
|
|
957
|
+
this.wsClient.on("room:subscribed", (data) => this.emit("room:subscribed", data));
|
|
958
|
+
this.wsClient.on("room:unsubscribed", (data) => this.emit("room:unsubscribed", data));
|
|
959
|
+
|
|
960
|
+
// Forward room events from RoomManager (if any direct emissions are added later)
|
|
961
|
+
this.rooms.on("room:subscribed", (data) => this.emit("room:subscribed", data));
|
|
962
|
+
this.rooms.on("room:unsubscribed", (data) => this.emit("room:unsubscribed", data));
|
|
963
|
+
|
|
964
|
+
// Forward webhook events from WebhookHandler
|
|
965
|
+
this.webhookHandler.on("webhook:sent", (payload, url) =>
|
|
966
|
+
this.emit("webhook:sent", payload, url)
|
|
967
|
+
);
|
|
968
|
+
this.webhookHandler.on("webhook:success", (response, url) =>
|
|
969
|
+
this.emit("webhook:success", response, url)
|
|
970
|
+
);
|
|
971
|
+
this.webhookHandler.on("webhook:error", (error, url) => this.emit("webhook:error", error, url));
|
|
972
|
+
this.webhookHandler.on("webhook:retry", (attempt, url) =>
|
|
973
|
+
this.emit("webhook:retry", attempt, url)
|
|
974
|
+
);
|
|
975
|
+
|
|
976
|
+
// Forward error events from ConnectionManager
|
|
977
|
+
this.connection.on("error", (error) => {
|
|
978
|
+
this.emit("error", error);
|
|
979
|
+
// Fire and forget - don't block event emission
|
|
980
|
+
this.webhookHandler
|
|
981
|
+
.sendWebhook("error", error, { code: error.code })
|
|
982
|
+
.catch((webhookError) => {
|
|
983
|
+
this.logger.error("Failed to send webhook for error event", webhookError);
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
// Forward lifecycle events from ConnectionManager
|
|
988
|
+
this.connection.on("ready", () => this.emit("ready"));
|
|
989
|
+
this.connection.on("disconnect", () => this.emit("disconnect"));
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Create default logger using pino
|
|
994
|
+
*/
|
|
995
|
+
private createDefaultLogger(): Logger {
|
|
996
|
+
return createPinoLogger(this.config.logLevel ?? "info", "TeneoSDK");
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/**
|
|
1000
|
+
* Creates a new SDK configuration builder for fluent configuration.
|
|
1001
|
+
* The builder pattern provides a more intuitive way to configure the SDK
|
|
1002
|
+
* with method chaining and validation at each step.
|
|
1003
|
+
*
|
|
1004
|
+
* @returns A new SDKConfigBuilder instance for fluent configuration
|
|
1005
|
+
*
|
|
1006
|
+
* @example
|
|
1007
|
+
* ```typescript
|
|
1008
|
+
* const sdk = TeneoSDK.builder()
|
|
1009
|
+
* .wsUrl('wss://teneo.example.com')
|
|
1010
|
+
* .privateKey('0x...')
|
|
1011
|
+
* .withAutoJoinRooms(['general'])
|
|
1012
|
+
* .logLevel('debug')
|
|
1013
|
+
* .webhookUrl('https://api.example.com/webhooks')
|
|
1014
|
+
* .build();
|
|
1015
|
+
*
|
|
1016
|
+
* await sdk.connect();
|
|
1017
|
+
* ```
|
|
1018
|
+
*/
|
|
1019
|
+
public static builder(): SDKConfigBuilder {
|
|
1020
|
+
return new SDKConfigBuilder();
|
|
1021
|
+
}
|
|
1022
|
+
}
|