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