agents-library 1.1.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/dist/base-agent.d.ts +172 -0
- package/dist/base-agent.d.ts.map +1 -0
- package/dist/base-agent.js +255 -0
- package/dist/base-agent.js.map +1 -0
- package/dist/base-bot.d.ts +282 -0
- package/dist/base-bot.d.ts.map +1 -0
- package/dist/base-bot.js +375 -0
- package/dist/base-bot.js.map +1 -0
- package/dist/common/result.d.ts +51 -0
- package/dist/common/result.d.ts.map +1 -0
- package/dist/common/result.js +45 -0
- package/dist/common/result.js.map +1 -0
- package/dist/common/types.d.ts +57 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/common/types.js +42 -0
- package/dist/common/types.js.map +1 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/kadi-event-publisher.d.ts +163 -0
- package/dist/kadi-event-publisher.d.ts.map +1 -0
- package/dist/kadi-event-publisher.js +286 -0
- package/dist/kadi-event-publisher.js.map +1 -0
- package/dist/memory/arcadedb-adapter.d.ts +159 -0
- package/dist/memory/arcadedb-adapter.d.ts.map +1 -0
- package/dist/memory/arcadedb-adapter.js +314 -0
- package/dist/memory/arcadedb-adapter.js.map +1 -0
- package/dist/memory/file-storage-adapter.d.ts +122 -0
- package/dist/memory/file-storage-adapter.d.ts.map +1 -0
- package/dist/memory/file-storage-adapter.js +352 -0
- package/dist/memory/file-storage-adapter.js.map +1 -0
- package/dist/memory/memory-service.d.ts +208 -0
- package/dist/memory/memory-service.d.ts.map +1 -0
- package/dist/memory/memory-service.js +410 -0
- package/dist/memory/memory-service.js.map +1 -0
- package/dist/memory/types.d.ts +126 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +41 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/producer-tool-utils.d.ts +474 -0
- package/dist/producer-tool-utils.d.ts.map +1 -0
- package/dist/producer-tool-utils.js +664 -0
- package/dist/producer-tool-utils.js.map +1 -0
- package/dist/providers/anthropic-provider.d.ts +160 -0
- package/dist/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/providers/anthropic-provider.js +527 -0
- package/dist/providers/anthropic-provider.js.map +1 -0
- package/dist/providers/model-manager-provider.d.ts +91 -0
- package/dist/providers/model-manager-provider.d.ts.map +1 -0
- package/dist/providers/model-manager-provider.js +355 -0
- package/dist/providers/model-manager-provider.js.map +1 -0
- package/dist/providers/provider-manager.d.ts +111 -0
- package/dist/providers/provider-manager.d.ts.map +1 -0
- package/dist/providers/provider-manager.js +337 -0
- package/dist/providers/provider-manager.js.map +1 -0
- package/dist/providers/types.d.ts +145 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +23 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/shadow-agent-factory.d.ts +623 -0
- package/dist/shadow-agent-factory.d.ts.map +1 -0
- package/dist/shadow-agent-factory.js +1117 -0
- package/dist/shadow-agent-factory.js.map +1 -0
- package/dist/types/agent-config.d.ts +307 -0
- package/dist/types/agent-config.d.ts.map +1 -0
- package/dist/types/agent-config.js +15 -0
- package/dist/types/agent-config.js.map +1 -0
- package/dist/types/event-schemas.d.ts +358 -0
- package/dist/types/event-schemas.d.ts.map +1 -0
- package/dist/types/event-schemas.js +188 -0
- package/dist/types/event-schemas.js.map +1 -0
- package/dist/types/tool-schemas.d.ts +498 -0
- package/dist/types/tool-schemas.d.ts.map +1 -0
- package/dist/types/tool-schemas.js +457 -0
- package/dist/types/tool-schemas.js.map +1 -0
- package/dist/utils/logger.d.ts +135 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +205 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/timer.d.ts +186 -0
- package/dist/utils/timer.d.ts.map +1 -0
- package/dist/utils/timer.js +211 -0
- package/dist/utils/timer.js.map +1 -0
- package/dist/worker-agent-factory.d.ts +688 -0
- package/dist/worker-agent-factory.d.ts.map +1 -0
- package/dist/worker-agent-factory.js +1517 -0
- package/dist/worker-agent-factory.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Bot Abstract Class for Platform-Agnostic Bot Logic
|
|
3
|
+
* ========================================================
|
|
4
|
+
*
|
|
5
|
+
* Provides shared functionality for all platform-specific bots (Slack, Discord, etc.)
|
|
6
|
+
* Eliminates code duplication by consolidating common patterns:
|
|
7
|
+
* - Circuit breaker pattern for fault tolerance
|
|
8
|
+
* - Exponential backoff retry logic
|
|
9
|
+
* - Metrics tracking and monitoring
|
|
10
|
+
* - Tool invocation with resilience
|
|
11
|
+
*
|
|
12
|
+
* This is an abstract class - cannot be instantiated directly.
|
|
13
|
+
* Platform-specific bots must extend this and implement abstract methods.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* export class SlackBot extends BaseBot {
|
|
18
|
+
* async handleMention(event: SlackMentionEvent): Promise<void> {
|
|
19
|
+
* // Slack-specific mention handling
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* async start(): Promise<void> {
|
|
23
|
+
* await super.initializeAbilityResponseSubscription();
|
|
24
|
+
* await this.subscribeToMentions();
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* stop(): void {
|
|
28
|
+
* // Cleanup logic
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
34
|
+
import type { KadiClient } from '@kadi.build/core';
|
|
35
|
+
import type { ProviderManager } from './providers/provider-manager.js';
|
|
36
|
+
import type { MemoryService } from './memory/memory-service.js';
|
|
37
|
+
/**
|
|
38
|
+
* Base configuration required by all bots
|
|
39
|
+
*/
|
|
40
|
+
export interface BaseBotConfig {
|
|
41
|
+
/** KĀDI client instance for event subscription and tool invocation */
|
|
42
|
+
client: KadiClient;
|
|
43
|
+
/** Anthropic API key for Claude integration */
|
|
44
|
+
anthropicApiKey: string;
|
|
45
|
+
/** Bot user ID for topic routing (platform-specific format) */
|
|
46
|
+
botUserId: string;
|
|
47
|
+
/** Optional provider manager for LLM operations (shared service) */
|
|
48
|
+
providerManager?: ProviderManager;
|
|
49
|
+
/** Optional memory service for conversation context (shared service) */
|
|
50
|
+
memoryService?: MemoryService;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Abstract base class for platform-agnostic bot logic
|
|
54
|
+
*
|
|
55
|
+
* Provides common functionality shared across all platform bots:
|
|
56
|
+
* - Circuit breaker for fault tolerance
|
|
57
|
+
* - Retry logic with exponential backoff
|
|
58
|
+
* - Metrics tracking
|
|
59
|
+
* - Tool invocation helpers
|
|
60
|
+
*
|
|
61
|
+
* Platform-specific bots (SlackBot, DiscordBot) extend this class
|
|
62
|
+
* and implement the abstract methods.
|
|
63
|
+
*/
|
|
64
|
+
export declare abstract class BaseBot {
|
|
65
|
+
/** KĀDI client for broker communication */
|
|
66
|
+
protected client: KadiClient;
|
|
67
|
+
/** Anthropic API client for Claude integration */
|
|
68
|
+
protected anthropic: Anthropic;
|
|
69
|
+
/** Bot user ID for topic routing */
|
|
70
|
+
protected botUserId: string;
|
|
71
|
+
/** Optional provider manager for LLM operations */
|
|
72
|
+
protected providerManager?: ProviderManager;
|
|
73
|
+
/** Optional memory service for conversation context */
|
|
74
|
+
protected memoryService?: MemoryService;
|
|
75
|
+
/** Pending async tool responses (requestId -> Promise resolver) */
|
|
76
|
+
private pendingResponses;
|
|
77
|
+
/** Number of consecutive failures */
|
|
78
|
+
private failureCount;
|
|
79
|
+
/** Timestamp of last failure (for reset timeout) */
|
|
80
|
+
private lastFailureTime;
|
|
81
|
+
/** Maximum failures before circuit opens */
|
|
82
|
+
private readonly maxFailures;
|
|
83
|
+
/** Time in ms before circuit breaker resets */
|
|
84
|
+
private readonly resetTimeMs;
|
|
85
|
+
/** Whether circuit breaker is open (blocking requests) */
|
|
86
|
+
private isCircuitOpen;
|
|
87
|
+
/** Maximum retry attempts for failed operations */
|
|
88
|
+
private readonly maxRetries;
|
|
89
|
+
/** Base delay in ms for exponential backoff (1s, 2s, 4s) */
|
|
90
|
+
private readonly baseDelayMs;
|
|
91
|
+
/** Total number of requests processed */
|
|
92
|
+
private totalRequests;
|
|
93
|
+
/** Number of requests that timed out */
|
|
94
|
+
private timeoutCount;
|
|
95
|
+
/** Number of successful requests */
|
|
96
|
+
private successCount;
|
|
97
|
+
/**
|
|
98
|
+
* Create a new BaseBot instance
|
|
99
|
+
*
|
|
100
|
+
* @param config - Base bot configuration with client, API key, and bot ID
|
|
101
|
+
*/
|
|
102
|
+
constructor(config: BaseBotConfig);
|
|
103
|
+
/**
|
|
104
|
+
* Handle platform-specific mention event
|
|
105
|
+
*
|
|
106
|
+
* Subclasses must implement this to process @mentions for their platform.
|
|
107
|
+
*
|
|
108
|
+
* @param event - Platform-specific mention event (e.g., SlackMentionEvent, DiscordMentionEvent)
|
|
109
|
+
*/
|
|
110
|
+
protected abstract handleMention(event: any): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Start the bot and begin processing events
|
|
113
|
+
*
|
|
114
|
+
* Subclasses must implement this to:
|
|
115
|
+
* 1. Call initializeAbilityResponseSubscription()
|
|
116
|
+
* 2. Subscribe to platform-specific events
|
|
117
|
+
*/
|
|
118
|
+
abstract start(): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Stop the bot and cleanup resources
|
|
121
|
+
*
|
|
122
|
+
* Subclasses must implement this to unsubscribe from events
|
|
123
|
+
* and perform any platform-specific cleanup.
|
|
124
|
+
*/
|
|
125
|
+
abstract stop(): void;
|
|
126
|
+
/**
|
|
127
|
+
* Initialize ability response subscription
|
|
128
|
+
*
|
|
129
|
+
* Must be called by subclasses in their start() method
|
|
130
|
+
* before attempting to invoke tools or subscribe to events.
|
|
131
|
+
*
|
|
132
|
+
* Subscribes to async ability responses from kadi-broker.
|
|
133
|
+
*/
|
|
134
|
+
protected initializeAbilityResponseSubscription(): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Subscribe to kadi.ability.response notifications
|
|
137
|
+
*
|
|
138
|
+
* Handles async tool results from broker. When a tool returns {status: "pending"},
|
|
139
|
+
* the actual result arrives later as a kadi.ability.response notification.
|
|
140
|
+
*
|
|
141
|
+
* @private
|
|
142
|
+
*/
|
|
143
|
+
private subscribeToAbilityResponses;
|
|
144
|
+
/**
|
|
145
|
+
* Wait for async ability response from kadi-broker
|
|
146
|
+
*
|
|
147
|
+
* When a tool returns {status: "pending", requestId: "..."}, this method
|
|
148
|
+
* waits for the actual result to arrive via kadi.ability.response notification.
|
|
149
|
+
*
|
|
150
|
+
* @param requestId - Request ID from pending status response
|
|
151
|
+
* @param timeout - Timeout in milliseconds (default: 30000)
|
|
152
|
+
* @returns Promise that resolves with the actual tool result
|
|
153
|
+
* @throws Error if timeout expires before result arrives
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const result = await this.protocol.invokeTool({...});
|
|
158
|
+
* if (result?.status === 'pending') {
|
|
159
|
+
* const actualResult = await this.waitForAbilityResponse(result.requestId);
|
|
160
|
+
* return actualResult;
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
protected waitForAbilityResponse(requestId: string, timeout?: number): Promise<any>;
|
|
165
|
+
/**
|
|
166
|
+
* Sleep for specified milliseconds
|
|
167
|
+
*
|
|
168
|
+
* Used for exponential backoff delays in retry logic.
|
|
169
|
+
*
|
|
170
|
+
* @param ms - Milliseconds to sleep
|
|
171
|
+
*/
|
|
172
|
+
protected sleep(ms: number): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Check circuit breaker state and reset if needed
|
|
175
|
+
*
|
|
176
|
+
* Returns true if circuit is open (blocking requests).
|
|
177
|
+
* Automatically resets circuit after resetTimeMs has elapsed.
|
|
178
|
+
*
|
|
179
|
+
* @returns true if circuit is open, false if closed
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* if (this.checkCircuitBreaker()) {
|
|
184
|
+
* console.log('Circuit open - skipping request');
|
|
185
|
+
* return;
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
protected checkCircuitBreaker(): boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Record failure and update circuit breaker state
|
|
192
|
+
*
|
|
193
|
+
* Increments failure count and opens circuit if maxFailures threshold reached.
|
|
194
|
+
* Logs metrics every 10 requests.
|
|
195
|
+
*
|
|
196
|
+
* @param _error - Error object (for potential future use)
|
|
197
|
+
*/
|
|
198
|
+
protected recordFailure(_error: any): void;
|
|
199
|
+
/**
|
|
200
|
+
* Record success and reset failure counter
|
|
201
|
+
*
|
|
202
|
+
* Resets consecutive failure count when a request succeeds.
|
|
203
|
+
* Increments success metrics.
|
|
204
|
+
*/
|
|
205
|
+
protected recordSuccess(): void;
|
|
206
|
+
/**
|
|
207
|
+
* Reset circuit breaker state
|
|
208
|
+
*
|
|
209
|
+
* Manually resets circuit breaker and clears failure count.
|
|
210
|
+
* Use with caution - typically circuit should auto-reset.
|
|
211
|
+
*/
|
|
212
|
+
protected resetCircuitBreaker(): void;
|
|
213
|
+
/**
|
|
214
|
+
* Invoke KĀDI tool with retry logic and exponential backoff
|
|
215
|
+
*
|
|
216
|
+
* Automatically retries failed tool invocations with exponential backoff:
|
|
217
|
+
* - Attempt 1: Immediate
|
|
218
|
+
* - Attempt 2: 1s delay
|
|
219
|
+
* - Attempt 3: 2s delay
|
|
220
|
+
* - Attempt 4: 4s delay
|
|
221
|
+
*
|
|
222
|
+
* Only retries on timeout or network errors. Other errors fail immediately.
|
|
223
|
+
*
|
|
224
|
+
* @param params - Tool invocation parameters
|
|
225
|
+
* @param params.targetAgent - Target agent ID (e.g., 'mcp-server-slack')
|
|
226
|
+
* @param params.toolName - Tool name to invoke (e.g., 'send_slack_message')
|
|
227
|
+
* @param params.toolInput - Tool input parameters
|
|
228
|
+
* @param params.timeout - Timeout in milliseconds
|
|
229
|
+
* @param retryCount - Current retry attempt (internal, do not set)
|
|
230
|
+
* @returns Tool invocation result
|
|
231
|
+
* @throws Error if all retries exhausted
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* await this.invokeToolWithRetry({
|
|
236
|
+
* targetAgent: 'mcp-server-slack',
|
|
237
|
+
* toolName: 'send_slack_message',
|
|
238
|
+
* toolInput: { channel: 'C123', text: 'Hello' },
|
|
239
|
+
* timeout: 10000
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
protected invokeToolWithRetry(params: {
|
|
244
|
+
targetAgent: string;
|
|
245
|
+
toolName: string;
|
|
246
|
+
toolInput: any;
|
|
247
|
+
timeout: number;
|
|
248
|
+
}, retryCount?: number): Promise<any>;
|
|
249
|
+
/**
|
|
250
|
+
* Get current bot metrics
|
|
251
|
+
*
|
|
252
|
+
* Returns metrics for monitoring and debugging:
|
|
253
|
+
* - Total requests processed
|
|
254
|
+
* - Success count and rate
|
|
255
|
+
* - Timeout count and rate
|
|
256
|
+
* - Circuit breaker state
|
|
257
|
+
*
|
|
258
|
+
* @returns Metrics object
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const metrics = this.getMetrics();
|
|
263
|
+
* console.log(`Success rate: ${metrics.successRate}%`);
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
protected getMetrics(): {
|
|
267
|
+
totalRequests: number;
|
|
268
|
+
successCount: number;
|
|
269
|
+
timeoutCount: number;
|
|
270
|
+
successRate: number;
|
|
271
|
+
timeoutRate: number;
|
|
272
|
+
isCircuitOpen: boolean;
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* Log timeout and success metrics
|
|
276
|
+
*
|
|
277
|
+
* Logs formatted metrics to console for monitoring.
|
|
278
|
+
* Called automatically every 10 requests or can be called manually.
|
|
279
|
+
*/
|
|
280
|
+
protected logMetrics(): void;
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=base-bot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-bot.d.ts","sourceRoot":"","sources":["../src/base-bot.ts"],"names":[],"mappings":"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"}
|
package/dist/base-bot.js
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Bot Abstract Class for Platform-Agnostic Bot Logic
|
|
3
|
+
* ========================================================
|
|
4
|
+
*
|
|
5
|
+
* Provides shared functionality for all platform-specific bots (Slack, Discord, etc.)
|
|
6
|
+
* Eliminates code duplication by consolidating common patterns:
|
|
7
|
+
* - Circuit breaker pattern for fault tolerance
|
|
8
|
+
* - Exponential backoff retry logic
|
|
9
|
+
* - Metrics tracking and monitoring
|
|
10
|
+
* - Tool invocation with resilience
|
|
11
|
+
*
|
|
12
|
+
* This is an abstract class - cannot be instantiated directly.
|
|
13
|
+
* Platform-specific bots must extend this and implement abstract methods.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* export class SlackBot extends BaseBot {
|
|
18
|
+
* async handleMention(event: SlackMentionEvent): Promise<void> {
|
|
19
|
+
* // Slack-specific mention handling
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* async start(): Promise<void> {
|
|
23
|
+
* await super.initializeAbilityResponseSubscription();
|
|
24
|
+
* await this.subscribeToMentions();
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* stop(): void {
|
|
28
|
+
* // Cleanup logic
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
34
|
+
import { logger, MODULE_AGENT } from './utils/logger.js';
|
|
35
|
+
import { timer } from './utils/timer.js';
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Abstract Base Bot Class
|
|
38
|
+
// ============================================================================
|
|
39
|
+
/**
|
|
40
|
+
* Abstract base class for platform-agnostic bot logic
|
|
41
|
+
*
|
|
42
|
+
* Provides common functionality shared across all platform bots:
|
|
43
|
+
* - Circuit breaker for fault tolerance
|
|
44
|
+
* - Retry logic with exponential backoff
|
|
45
|
+
* - Metrics tracking
|
|
46
|
+
* - Tool invocation helpers
|
|
47
|
+
*
|
|
48
|
+
* Platform-specific bots (SlackBot, DiscordBot) extend this class
|
|
49
|
+
* and implement the abstract methods.
|
|
50
|
+
*/
|
|
51
|
+
export class BaseBot {
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Protected Properties (accessible to subclasses)
|
|
54
|
+
// ============================================================================
|
|
55
|
+
/** KĀDI client for broker communication */
|
|
56
|
+
client;
|
|
57
|
+
/** Anthropic API client for Claude integration */
|
|
58
|
+
anthropic;
|
|
59
|
+
/** Bot user ID for topic routing */
|
|
60
|
+
botUserId;
|
|
61
|
+
/** Optional provider manager for LLM operations */
|
|
62
|
+
providerManager;
|
|
63
|
+
/** Optional memory service for conversation context */
|
|
64
|
+
memoryService;
|
|
65
|
+
/** Pending async tool responses (requestId -> Promise resolver) */
|
|
66
|
+
pendingResponses = new Map();
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Circuit Breaker State (private)
|
|
69
|
+
// ============================================================================
|
|
70
|
+
/** Number of consecutive failures */
|
|
71
|
+
failureCount = 0;
|
|
72
|
+
/** Timestamp of last failure (for reset timeout) */
|
|
73
|
+
lastFailureTime = 0;
|
|
74
|
+
/** Maximum failures before circuit opens */
|
|
75
|
+
maxFailures = 5;
|
|
76
|
+
/** Time in ms before circuit breaker resets */
|
|
77
|
+
resetTimeMs = 60000; // 1 minute
|
|
78
|
+
/** Whether circuit breaker is open (blocking requests) */
|
|
79
|
+
isCircuitOpen = false;
|
|
80
|
+
// ============================================================================
|
|
81
|
+
// Retry Configuration (private)
|
|
82
|
+
// ============================================================================
|
|
83
|
+
/** Maximum retry attempts for failed operations */
|
|
84
|
+
maxRetries = 3;
|
|
85
|
+
/** Base delay in ms for exponential backoff (1s, 2s, 4s) */
|
|
86
|
+
baseDelayMs = 1000;
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Metrics Tracking (private)
|
|
89
|
+
// ============================================================================
|
|
90
|
+
/** Total number of requests processed */
|
|
91
|
+
totalRequests = 0;
|
|
92
|
+
/** Number of requests that timed out */
|
|
93
|
+
timeoutCount = 0;
|
|
94
|
+
/** Number of successful requests */
|
|
95
|
+
successCount = 0;
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// Constructor
|
|
98
|
+
// ============================================================================
|
|
99
|
+
/**
|
|
100
|
+
* Create a new BaseBot instance
|
|
101
|
+
*
|
|
102
|
+
* @param config - Base bot configuration with client, API key, and bot ID
|
|
103
|
+
*/
|
|
104
|
+
constructor(config) {
|
|
105
|
+
this.client = config.client;
|
|
106
|
+
this.anthropic = new Anthropic({ apiKey: config.anthropicApiKey });
|
|
107
|
+
this.botUserId = config.botUserId;
|
|
108
|
+
this.providerManager = config.providerManager;
|
|
109
|
+
this.memoryService = config.memoryService;
|
|
110
|
+
}
|
|
111
|
+
// ============================================================================
|
|
112
|
+
// Protected Helper Methods (available to subclasses)
|
|
113
|
+
// ============================================================================
|
|
114
|
+
/**
|
|
115
|
+
* Initialize ability response subscription
|
|
116
|
+
*
|
|
117
|
+
* Must be called by subclasses in their start() method
|
|
118
|
+
* before attempting to invoke tools or subscribe to events.
|
|
119
|
+
*
|
|
120
|
+
* Subscribes to async ability responses from kadi-broker.
|
|
121
|
+
*/
|
|
122
|
+
async initializeAbilityResponseSubscription() {
|
|
123
|
+
// Subscribe to async ability responses from kadi-broker
|
|
124
|
+
await this.subscribeToAbilityResponses();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Subscribe to kadi.ability.response notifications
|
|
128
|
+
*
|
|
129
|
+
* Handles async tool results from broker. When a tool returns {status: "pending"},
|
|
130
|
+
* the actual result arrives later as a kadi.ability.response notification.
|
|
131
|
+
*
|
|
132
|
+
* @private
|
|
133
|
+
*/
|
|
134
|
+
async subscribeToAbilityResponses() {
|
|
135
|
+
// Subscribe to kadi.ability.response events via kadi-core v0.6.0 subscribe API
|
|
136
|
+
await this.client.subscribe('kadi.ability.response', (event) => {
|
|
137
|
+
const { requestId, result, error } = event || {};
|
|
138
|
+
const pending = this.pendingResponses.get(requestId);
|
|
139
|
+
if (!pending) {
|
|
140
|
+
// This response is for a different request or already handled
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Clear timeout timer
|
|
144
|
+
clearTimeout(pending.timer);
|
|
145
|
+
this.pendingResponses.delete(requestId);
|
|
146
|
+
// Resolve or reject the promise
|
|
147
|
+
if (error) {
|
|
148
|
+
pending.reject(new Error(`Async tool failed: ${error}`));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
pending.resolve(result);
|
|
152
|
+
}
|
|
153
|
+
}, { broker: 'default' });
|
|
154
|
+
logger.info(MODULE_AGENT, 'Subscribed to kadi.ability.response notifications', timer.elapsed('main'));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Wait for async ability response from kadi-broker
|
|
158
|
+
*
|
|
159
|
+
* When a tool returns {status: "pending", requestId: "..."}, this method
|
|
160
|
+
* waits for the actual result to arrive via kadi.ability.response notification.
|
|
161
|
+
*
|
|
162
|
+
* @param requestId - Request ID from pending status response
|
|
163
|
+
* @param timeout - Timeout in milliseconds (default: 30000)
|
|
164
|
+
* @returns Promise that resolves with the actual tool result
|
|
165
|
+
* @throws Error if timeout expires before result arrives
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* const result = await this.protocol.invokeTool({...});
|
|
170
|
+
* if (result?.status === 'pending') {
|
|
171
|
+
* const actualResult = await this.waitForAbilityResponse(result.requestId);
|
|
172
|
+
* return actualResult;
|
|
173
|
+
* }
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
waitForAbilityResponse(requestId, timeout = 30000) {
|
|
177
|
+
return new Promise((resolve, reject) => {
|
|
178
|
+
// Setup timeout
|
|
179
|
+
const timer = setTimeout(() => {
|
|
180
|
+
this.pendingResponses.delete(requestId);
|
|
181
|
+
reject(new Error(`Timeout waiting for async tool result: ${requestId}`));
|
|
182
|
+
}, timeout);
|
|
183
|
+
// Register promise resolver
|
|
184
|
+
this.pendingResponses.set(requestId, {
|
|
185
|
+
resolve,
|
|
186
|
+
reject,
|
|
187
|
+
timer
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Sleep for specified milliseconds
|
|
193
|
+
*
|
|
194
|
+
* Used for exponential backoff delays in retry logic.
|
|
195
|
+
*
|
|
196
|
+
* @param ms - Milliseconds to sleep
|
|
197
|
+
*/
|
|
198
|
+
sleep(ms) {
|
|
199
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check circuit breaker state and reset if needed
|
|
203
|
+
*
|
|
204
|
+
* Returns true if circuit is open (blocking requests).
|
|
205
|
+
* Automatically resets circuit after resetTimeMs has elapsed.
|
|
206
|
+
*
|
|
207
|
+
* @returns true if circuit is open, false if closed
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```typescript
|
|
211
|
+
* if (this.checkCircuitBreaker()) {
|
|
212
|
+
* console.log('Circuit open - skipping request');
|
|
213
|
+
* return;
|
|
214
|
+
* }
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
checkCircuitBreaker() {
|
|
218
|
+
const now = Date.now();
|
|
219
|
+
// Reset circuit if enough time has passed
|
|
220
|
+
if (this.isCircuitOpen && (now - this.lastFailureTime) > this.resetTimeMs) {
|
|
221
|
+
console.log('🔧 Circuit breaker reset - attempting recovery');
|
|
222
|
+
this.isCircuitOpen = false;
|
|
223
|
+
this.failureCount = 0;
|
|
224
|
+
}
|
|
225
|
+
return this.isCircuitOpen;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Record failure and update circuit breaker state
|
|
229
|
+
*
|
|
230
|
+
* Increments failure count and opens circuit if maxFailures threshold reached.
|
|
231
|
+
* Logs metrics every 10 requests.
|
|
232
|
+
*
|
|
233
|
+
* @param _error - Error object (for potential future use)
|
|
234
|
+
*/
|
|
235
|
+
recordFailure(_error) {
|
|
236
|
+
this.failureCount++;
|
|
237
|
+
this.lastFailureTime = Date.now();
|
|
238
|
+
this.timeoutCount++;
|
|
239
|
+
if (this.failureCount >= this.maxFailures && !this.isCircuitOpen) {
|
|
240
|
+
this.isCircuitOpen = true;
|
|
241
|
+
console.error(`⚡ Circuit breaker OPEN after ${this.failureCount} failures`);
|
|
242
|
+
console.error(` Will retry after ${this.resetTimeMs / 1000} seconds`);
|
|
243
|
+
}
|
|
244
|
+
// Log timeout metrics every 10 requests
|
|
245
|
+
if (this.totalRequests % 10 === 0) {
|
|
246
|
+
this.logMetrics();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Record success and reset failure counter
|
|
251
|
+
*
|
|
252
|
+
* Resets consecutive failure count when a request succeeds.
|
|
253
|
+
* Increments success metrics.
|
|
254
|
+
*/
|
|
255
|
+
recordSuccess() {
|
|
256
|
+
if (this.failureCount > 0) {
|
|
257
|
+
console.log(`✅ Request succeeded - resetting failure count (was ${this.failureCount})`);
|
|
258
|
+
}
|
|
259
|
+
this.failureCount = 0;
|
|
260
|
+
this.successCount++;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Reset circuit breaker state
|
|
264
|
+
*
|
|
265
|
+
* Manually resets circuit breaker and clears failure count.
|
|
266
|
+
* Use with caution - typically circuit should auto-reset.
|
|
267
|
+
*/
|
|
268
|
+
resetCircuitBreaker() {
|
|
269
|
+
this.isCircuitOpen = false;
|
|
270
|
+
this.failureCount = 0;
|
|
271
|
+
this.lastFailureTime = 0;
|
|
272
|
+
console.log('🔧 Circuit breaker manually reset');
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Invoke KĀDI tool with retry logic and exponential backoff
|
|
276
|
+
*
|
|
277
|
+
* Automatically retries failed tool invocations with exponential backoff:
|
|
278
|
+
* - Attempt 1: Immediate
|
|
279
|
+
* - Attempt 2: 1s delay
|
|
280
|
+
* - Attempt 3: 2s delay
|
|
281
|
+
* - Attempt 4: 4s delay
|
|
282
|
+
*
|
|
283
|
+
* Only retries on timeout or network errors. Other errors fail immediately.
|
|
284
|
+
*
|
|
285
|
+
* @param params - Tool invocation parameters
|
|
286
|
+
* @param params.targetAgent - Target agent ID (e.g., 'mcp-server-slack')
|
|
287
|
+
* @param params.toolName - Tool name to invoke (e.g., 'send_slack_message')
|
|
288
|
+
* @param params.toolInput - Tool input parameters
|
|
289
|
+
* @param params.timeout - Timeout in milliseconds
|
|
290
|
+
* @param retryCount - Current retry attempt (internal, do not set)
|
|
291
|
+
* @returns Tool invocation result
|
|
292
|
+
* @throws Error if all retries exhausted
|
|
293
|
+
*
|
|
294
|
+
* @example
|
|
295
|
+
* ```typescript
|
|
296
|
+
* await this.invokeToolWithRetry({
|
|
297
|
+
* targetAgent: 'mcp-server-slack',
|
|
298
|
+
* toolName: 'send_slack_message',
|
|
299
|
+
* toolInput: { channel: 'C123', text: 'Hello' },
|
|
300
|
+
* timeout: 10000
|
|
301
|
+
* });
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
async invokeToolWithRetry(params, retryCount = 0) {
|
|
305
|
+
this.totalRequests++;
|
|
306
|
+
try {
|
|
307
|
+
const result = await this.client.invokeRemote(params.toolName, params.toolInput, { timeout: params.timeout });
|
|
308
|
+
this.recordSuccess();
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
const isTimeout = error.message?.includes('timeout');
|
|
313
|
+
const isNetworkError = error.message?.includes('ECONNREFUSED') ||
|
|
314
|
+
error.message?.includes('ENOTFOUND');
|
|
315
|
+
// Only retry on timeout or network errors
|
|
316
|
+
if ((isTimeout || isNetworkError) && retryCount < this.maxRetries) {
|
|
317
|
+
const delayMs = this.baseDelayMs * Math.pow(2, retryCount);
|
|
318
|
+
console.warn(`⚠️ Request failed (${error.message}), retrying in ${delayMs}ms (attempt ${retryCount + 1}/${this.maxRetries})...`);
|
|
319
|
+
await this.sleep(delayMs);
|
|
320
|
+
return this.invokeToolWithRetry(params, retryCount + 1);
|
|
321
|
+
}
|
|
322
|
+
// Record failure after all retries exhausted
|
|
323
|
+
this.recordFailure(error);
|
|
324
|
+
throw error;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Get current bot metrics
|
|
329
|
+
*
|
|
330
|
+
* Returns metrics for monitoring and debugging:
|
|
331
|
+
* - Total requests processed
|
|
332
|
+
* - Success count and rate
|
|
333
|
+
* - Timeout count and rate
|
|
334
|
+
* - Circuit breaker state
|
|
335
|
+
*
|
|
336
|
+
* @returns Metrics object
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```typescript
|
|
340
|
+
* const metrics = this.getMetrics();
|
|
341
|
+
* console.log(`Success rate: ${metrics.successRate}%`);
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
getMetrics() {
|
|
345
|
+
const successRate = this.totalRequests > 0
|
|
346
|
+
? (this.successCount / this.totalRequests) * 100
|
|
347
|
+
: 0;
|
|
348
|
+
const timeoutRate = this.totalRequests > 0
|
|
349
|
+
? (this.timeoutCount / this.totalRequests) * 100
|
|
350
|
+
: 0;
|
|
351
|
+
return {
|
|
352
|
+
totalRequests: this.totalRequests,
|
|
353
|
+
successCount: this.successCount,
|
|
354
|
+
timeoutCount: this.timeoutCount,
|
|
355
|
+
successRate: parseFloat(successRate.toFixed(1)),
|
|
356
|
+
timeoutRate: parseFloat(timeoutRate.toFixed(1)),
|
|
357
|
+
isCircuitOpen: this.isCircuitOpen
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Log timeout and success metrics
|
|
362
|
+
*
|
|
363
|
+
* Logs formatted metrics to console for monitoring.
|
|
364
|
+
* Called automatically every 10 requests or can be called manually.
|
|
365
|
+
*/
|
|
366
|
+
logMetrics() {
|
|
367
|
+
const metrics = this.getMetrics();
|
|
368
|
+
console.log('📊 Bot Metrics:');
|
|
369
|
+
console.log(` Total Requests: ${metrics.totalRequests}`);
|
|
370
|
+
console.log(` Successes: ${metrics.successCount} (${metrics.successRate}%)`);
|
|
371
|
+
console.log(` Timeouts: ${metrics.timeoutCount} (${metrics.timeoutRate}%)`);
|
|
372
|
+
console.log(` Circuit Breaker: ${metrics.isCircuitOpen ? 'OPEN' : 'CLOSED'}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=base-bot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-bot.js","sourceRoot":"","sources":["../src/base-bot.ts"],"names":[],"mappings":"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"}
|