@kb-labs/core-resource-broker 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/README.md +96 -0
- package/dist/index.d.ts +1217 -0
- package/dist/index.js +1418 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1217 @@
|
|
|
1
|
+
import { StateBroker } from '@kb-labs/core-state-broker';
|
|
2
|
+
import { ILLM, LLMOptions, LLMResponse, LLMProtocolCapabilities, LLMMessage, LLMToolCallOptions, LLMToolCallResponse, IEmbeddings, IVectorStore, VectorFilter, VectorSearchResult, VectorRecord } from '@kb-labs/core-platform';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @module @kb-labs/core-resource-broker/types
|
|
6
|
+
* Type definitions for the Resource Broker system.
|
|
7
|
+
*
|
|
8
|
+
* The Resource Broker provides centralized queue management, rate limiting,
|
|
9
|
+
* and retry logic for heavy platform resources (LLM, Embeddings, VectorStore).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Rate limiting configuration for a resource.
|
|
13
|
+
* Supports multiple rate limiting strategies (TPM, RPM, RPS, concurrent).
|
|
14
|
+
*/
|
|
15
|
+
interface RateLimitConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Tokens per minute limit (e.g., OpenAI TPM)
|
|
18
|
+
* If undefined, no token-based rate limiting is applied
|
|
19
|
+
*/
|
|
20
|
+
tokensPerMinute?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Requests per minute limit (e.g., OpenAI RPM)
|
|
23
|
+
* If undefined, no request-per-minute rate limiting is applied
|
|
24
|
+
*/
|
|
25
|
+
requestsPerMinute?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Requests per second limit
|
|
28
|
+
* Some APIs (like Sber) use RPS instead of RPM
|
|
29
|
+
*/
|
|
30
|
+
requestsPerSecond?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Maximum tokens per single request
|
|
33
|
+
* Provider-specific limit
|
|
34
|
+
*/
|
|
35
|
+
maxTokensPerRequest?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Maximum concurrent requests
|
|
38
|
+
* For local models - GPU/CPU concurrency limit
|
|
39
|
+
*/
|
|
40
|
+
maxConcurrentRequests?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Safety margin (0-1, default 0.9)
|
|
43
|
+
* Use only X% of the limit to avoid hitting exact boundaries
|
|
44
|
+
*/
|
|
45
|
+
safetyMargin?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Result of attempting to acquire rate limit capacity.
|
|
49
|
+
*/
|
|
50
|
+
interface AcquireResult {
|
|
51
|
+
/** Whether the request is allowed to proceed */
|
|
52
|
+
allowed: boolean;
|
|
53
|
+
/** Milliseconds to wait if not allowed */
|
|
54
|
+
waitTimeMs?: number;
|
|
55
|
+
/** Remaining tokens in current window */
|
|
56
|
+
tokensRemaining?: number;
|
|
57
|
+
/** Remaining requests in current window */
|
|
58
|
+
requestsRemaining?: number;
|
|
59
|
+
/** Current active concurrent requests */
|
|
60
|
+
activeRequests?: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Statistics for a rate-limited resource.
|
|
64
|
+
*/
|
|
65
|
+
interface RateLimitStats {
|
|
66
|
+
/** Resource identifier */
|
|
67
|
+
resource: string;
|
|
68
|
+
/** Tokens used in current minute window */
|
|
69
|
+
tokensThisMinute: number;
|
|
70
|
+
/** Requests made in current minute window */
|
|
71
|
+
requestsThisMinute: number;
|
|
72
|
+
/** Requests made in current second window */
|
|
73
|
+
requestsThisSecond: number;
|
|
74
|
+
/** Currently active requests */
|
|
75
|
+
activeRequests: number;
|
|
76
|
+
/** Total requests made since start */
|
|
77
|
+
totalRequests: number;
|
|
78
|
+
/** Total tokens used since start */
|
|
79
|
+
totalTokens: number;
|
|
80
|
+
/** Number of times capacity was unavailable */
|
|
81
|
+
waitCount: number;
|
|
82
|
+
/** Total time spent waiting (ms) */
|
|
83
|
+
totalWaitTime: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Backend abstraction for rate limit state storage.
|
|
87
|
+
* Allows swapping between in-memory and distributed storage.
|
|
88
|
+
*/
|
|
89
|
+
interface RateLimitBackend {
|
|
90
|
+
/**
|
|
91
|
+
* Atomically check limit and reserve capacity.
|
|
92
|
+
*
|
|
93
|
+
* @param resource - Resource identifier (e.g., 'llm', 'embeddings')
|
|
94
|
+
* @param tokens - Estimated tokens for this request
|
|
95
|
+
* @param config - Rate limit configuration
|
|
96
|
+
* @returns Acquire result with allowed/waitTime
|
|
97
|
+
*/
|
|
98
|
+
acquire(resource: string, tokens: number, config: RateLimitConfig): Promise<AcquireResult>;
|
|
99
|
+
/**
|
|
100
|
+
* Release a concurrent request slot.
|
|
101
|
+
*
|
|
102
|
+
* @param resource - Resource identifier
|
|
103
|
+
*/
|
|
104
|
+
release(resource: string): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Get current statistics for a resource.
|
|
107
|
+
*
|
|
108
|
+
* @param resource - Resource identifier
|
|
109
|
+
*/
|
|
110
|
+
getStats(resource: string): Promise<RateLimitStats>;
|
|
111
|
+
/**
|
|
112
|
+
* Reset statistics for a resource.
|
|
113
|
+
*
|
|
114
|
+
* @param resource - Resource identifier
|
|
115
|
+
*/
|
|
116
|
+
reset(resource: string): Promise<void>;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Priority levels for resource requests.
|
|
120
|
+
* - high: User-facing operations (commit, interactive queries)
|
|
121
|
+
* - normal: Background operations with reasonable latency expectations
|
|
122
|
+
* - low: Analytics, batch processing, non-urgent tasks
|
|
123
|
+
*/
|
|
124
|
+
type ResourcePriority = 'high' | 'normal' | 'low';
|
|
125
|
+
/**
|
|
126
|
+
* Request to execute a resource operation.
|
|
127
|
+
*/
|
|
128
|
+
interface ResourceRequest {
|
|
129
|
+
/** Unique request identifier */
|
|
130
|
+
id: string;
|
|
131
|
+
/** Resource type ('llm', 'embeddings', 'vectorStore') */
|
|
132
|
+
resource: string;
|
|
133
|
+
/** Operation name ('complete', 'embed', 'search') */
|
|
134
|
+
operation: string;
|
|
135
|
+
/** Arguments to pass to the operation */
|
|
136
|
+
args: unknown[];
|
|
137
|
+
/** Request priority */
|
|
138
|
+
priority: ResourcePriority;
|
|
139
|
+
/** Estimated tokens for rate limiting (optional) */
|
|
140
|
+
estimatedTokens?: number;
|
|
141
|
+
/** Request timeout in ms (optional, default: 60000) */
|
|
142
|
+
timeout?: number;
|
|
143
|
+
/** Max retry attempts (optional, default: 3) */
|
|
144
|
+
maxRetries?: number;
|
|
145
|
+
/** Timestamp when request was created */
|
|
146
|
+
createdAt: number;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Response from a resource operation.
|
|
150
|
+
*/
|
|
151
|
+
interface ResourceResponse<T = unknown> {
|
|
152
|
+
/** Whether the operation succeeded */
|
|
153
|
+
success: boolean;
|
|
154
|
+
/** Result data if successful */
|
|
155
|
+
data?: T;
|
|
156
|
+
/** Error if failed */
|
|
157
|
+
error?: Error;
|
|
158
|
+
/** Number of retry attempts made */
|
|
159
|
+
retries: number;
|
|
160
|
+
/** Time spent waiting in queue (ms) */
|
|
161
|
+
waitTime: number;
|
|
162
|
+
/** Time spent executing the operation (ms) */
|
|
163
|
+
processingTime: number;
|
|
164
|
+
/** Total time from request to response (ms) */
|
|
165
|
+
totalTime: number;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Queue item wrapping a request with execution context.
|
|
169
|
+
*/
|
|
170
|
+
interface QueueItem {
|
|
171
|
+
/** The resource request */
|
|
172
|
+
request: ResourceRequest;
|
|
173
|
+
/** Resolve function to complete the promise */
|
|
174
|
+
resolve: (response: ResourceResponse) => void;
|
|
175
|
+
/** Reject function to fail the promise */
|
|
176
|
+
reject: (error: Error) => void;
|
|
177
|
+
/** Timestamp when added to queue */
|
|
178
|
+
enqueuedAt: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Configuration for a registered resource.
|
|
182
|
+
*/
|
|
183
|
+
interface ResourceConfig {
|
|
184
|
+
/** Rate limit configuration or preset name */
|
|
185
|
+
rateLimits?: RateLimitConfig | string;
|
|
186
|
+
/** Maximum retry attempts */
|
|
187
|
+
maxRetries?: number;
|
|
188
|
+
/** Base delay for exponential backoff (ms) */
|
|
189
|
+
baseDelay?: number;
|
|
190
|
+
/** Maximum delay between retries (ms) */
|
|
191
|
+
maxDelay?: number;
|
|
192
|
+
/** Request timeout (ms) */
|
|
193
|
+
timeout?: number;
|
|
194
|
+
/** The actual executor function */
|
|
195
|
+
executor: ResourceExecutor;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Function that executes a resource operation.
|
|
199
|
+
*/
|
|
200
|
+
type ResourceExecutor = (operation: string, args: unknown[]) => Promise<unknown>;
|
|
201
|
+
/**
|
|
202
|
+
* Statistics for the resource broker.
|
|
203
|
+
*/
|
|
204
|
+
interface ResourceBrokerStats {
|
|
205
|
+
/** Stats per resource */
|
|
206
|
+
resources: Record<string, ResourceStats>;
|
|
207
|
+
/** Total requests processed */
|
|
208
|
+
totalRequests: number;
|
|
209
|
+
/** Total successful requests */
|
|
210
|
+
totalSuccess: number;
|
|
211
|
+
/** Total failed requests */
|
|
212
|
+
totalErrors: number;
|
|
213
|
+
/** Current queue size */
|
|
214
|
+
queueSize: number;
|
|
215
|
+
/** Uptime in milliseconds */
|
|
216
|
+
uptime: number;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Statistics for a single resource.
|
|
220
|
+
*/
|
|
221
|
+
interface ResourceStats {
|
|
222
|
+
/** Rate limit stats */
|
|
223
|
+
rateLimits: RateLimitStats;
|
|
224
|
+
/** Queue size for this resource */
|
|
225
|
+
queueSize: number;
|
|
226
|
+
/** Requests by priority */
|
|
227
|
+
queueByPriority: {
|
|
228
|
+
high: number;
|
|
229
|
+
normal: number;
|
|
230
|
+
low: number;
|
|
231
|
+
};
|
|
232
|
+
/** Total requests processed */
|
|
233
|
+
totalRequests: number;
|
|
234
|
+
/** Total successful requests */
|
|
235
|
+
totalSuccess: number;
|
|
236
|
+
/** Total failed requests */
|
|
237
|
+
totalErrors: number;
|
|
238
|
+
/** Average wait time (ms) */
|
|
239
|
+
avgWaitTime: number;
|
|
240
|
+
/** Average processing time (ms) */
|
|
241
|
+
avgProcessingTime: number;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Main resource broker interface.
|
|
245
|
+
* Coordinates queues, rate limiting, and execution for all resources.
|
|
246
|
+
*/
|
|
247
|
+
interface IResourceBroker {
|
|
248
|
+
/**
|
|
249
|
+
* Register a resource with its configuration.
|
|
250
|
+
*
|
|
251
|
+
* @param resource - Resource identifier
|
|
252
|
+
* @param config - Resource configuration
|
|
253
|
+
*/
|
|
254
|
+
register(resource: string, config: ResourceConfig): void;
|
|
255
|
+
/**
|
|
256
|
+
* Enqueue a request for execution.
|
|
257
|
+
* Returns a promise that resolves when the request completes.
|
|
258
|
+
*
|
|
259
|
+
* @param request - Resource request (without id and createdAt)
|
|
260
|
+
* @returns Response with result or error
|
|
261
|
+
*/
|
|
262
|
+
enqueue<T>(request: Omit<ResourceRequest, 'id' | 'createdAt'>): Promise<ResourceResponse<T>>;
|
|
263
|
+
/**
|
|
264
|
+
* Get broker statistics.
|
|
265
|
+
*/
|
|
266
|
+
getStats(): ResourceBrokerStats;
|
|
267
|
+
/**
|
|
268
|
+
* Graceful shutdown - drain queues and stop processing.
|
|
269
|
+
*/
|
|
270
|
+
shutdown(): Promise<void>;
|
|
271
|
+
/**
|
|
272
|
+
* Check if broker is shutting down.
|
|
273
|
+
*/
|
|
274
|
+
isShuttingDown(): boolean;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Error classification for retry logic.
|
|
278
|
+
*/
|
|
279
|
+
type ErrorType = 'rate_limit' | 'server_error' | 'timeout' | 'client_error' | 'network' | 'unknown';
|
|
280
|
+
/**
|
|
281
|
+
* Configuration for retry strategy.
|
|
282
|
+
*/
|
|
283
|
+
interface RetryConfig {
|
|
284
|
+
/** Maximum number of retry attempts */
|
|
285
|
+
maxRetries: number;
|
|
286
|
+
/** Base delay in ms (default: 1000) */
|
|
287
|
+
baseDelay: number;
|
|
288
|
+
/** Maximum delay in ms (default: 30000) */
|
|
289
|
+
maxDelay: number;
|
|
290
|
+
/** Jitter factor (0-1, default: 0.1) */
|
|
291
|
+
jitter: number;
|
|
292
|
+
/** Which error types to retry */
|
|
293
|
+
retryableErrors: ErrorType[];
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Default retry configuration.
|
|
297
|
+
*/
|
|
298
|
+
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
299
|
+
/**
|
|
300
|
+
* Default rate limit config (no limits).
|
|
301
|
+
*/
|
|
302
|
+
declare const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* @module @kb-labs/core-resource-broker/broker/resource-broker
|
|
306
|
+
* Main ResourceBroker implementation - coordinates queues, rate limiting, and execution.
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* ResourceBroker - Centralized coordinator for heavy platform resources.
|
|
311
|
+
*
|
|
312
|
+
* Features:
|
|
313
|
+
* - Priority queue (high/normal/low)
|
|
314
|
+
* - Rate limiting with configurable backend (in-memory or distributed)
|
|
315
|
+
* - Automatic retry with exponential backoff
|
|
316
|
+
* - Graceful shutdown
|
|
317
|
+
* - Per-resource statistics
|
|
318
|
+
*
|
|
319
|
+
* The platform doesn't know about plugins - only manages resources.
|
|
320
|
+
* Any caller can enqueue requests with appropriate priority.
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* ```typescript
|
|
324
|
+
* const backend = new InMemoryRateLimitBackend();
|
|
325
|
+
* const broker = new ResourceBroker(backend);
|
|
326
|
+
*
|
|
327
|
+
* // Register resources
|
|
328
|
+
* broker.register('llm', {
|
|
329
|
+
* rateLimits: 'openai-tier-2',
|
|
330
|
+
* executor: (op, args) => llmAdapter[op](...args),
|
|
331
|
+
* });
|
|
332
|
+
*
|
|
333
|
+
* // Enqueue request
|
|
334
|
+
* const response = await broker.enqueue({
|
|
335
|
+
* resource: 'llm',
|
|
336
|
+
* operation: 'complete',
|
|
337
|
+
* args: [prompt, options],
|
|
338
|
+
* priority: 'high',
|
|
339
|
+
* estimatedTokens: 1000,
|
|
340
|
+
* });
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
declare class ResourceBroker implements IResourceBroker {
|
|
344
|
+
private rateLimitBackend;
|
|
345
|
+
private resources;
|
|
346
|
+
private queue;
|
|
347
|
+
private processing;
|
|
348
|
+
private shuttingDown;
|
|
349
|
+
private startTime;
|
|
350
|
+
/**
|
|
351
|
+
* Active processing count per resource (for concurrent limit tracking).
|
|
352
|
+
*/
|
|
353
|
+
private activeProcessing;
|
|
354
|
+
constructor(rateLimitBackend: RateLimitBackend);
|
|
355
|
+
/**
|
|
356
|
+
* Register a resource with its configuration.
|
|
357
|
+
*
|
|
358
|
+
* @param resource - Resource identifier ('llm', 'embeddings', 'vectorStore')
|
|
359
|
+
* @param config - Resource configuration including executor
|
|
360
|
+
*/
|
|
361
|
+
register(resource: string, config: ResourceConfig): void;
|
|
362
|
+
/**
|
|
363
|
+
* Enqueue a request for execution.
|
|
364
|
+
*
|
|
365
|
+
* @param request - Resource request (without id and createdAt)
|
|
366
|
+
* @returns Promise that resolves with response when execution completes
|
|
367
|
+
*/
|
|
368
|
+
enqueue<T>(request: Omit<ResourceRequest, 'id' | 'createdAt'>): Promise<ResourceResponse<T>>;
|
|
369
|
+
/**
|
|
370
|
+
* Process queue items continuously.
|
|
371
|
+
*/
|
|
372
|
+
private processQueue;
|
|
373
|
+
/**
|
|
374
|
+
* Execute a single queue item with retry logic.
|
|
375
|
+
*/
|
|
376
|
+
private executeItem;
|
|
377
|
+
/**
|
|
378
|
+
* Get broker statistics.
|
|
379
|
+
*/
|
|
380
|
+
getStats(): ResourceBrokerStats;
|
|
381
|
+
/**
|
|
382
|
+
* Graceful shutdown - drain queues and stop processing.
|
|
383
|
+
*
|
|
384
|
+
* @param timeoutMs - Maximum time to wait for drain (default: 30000)
|
|
385
|
+
*/
|
|
386
|
+
shutdown(timeoutMs?: number): Promise<void>;
|
|
387
|
+
/**
|
|
388
|
+
* Check if broker is shutting down.
|
|
389
|
+
*/
|
|
390
|
+
isShuttingDown(): boolean;
|
|
391
|
+
/**
|
|
392
|
+
* Get registered resource names.
|
|
393
|
+
*/
|
|
394
|
+
getRegisteredResources(): string[];
|
|
395
|
+
/**
|
|
396
|
+
* Check if a resource is registered.
|
|
397
|
+
*/
|
|
398
|
+
hasResource(resource: string): boolean;
|
|
399
|
+
/**
|
|
400
|
+
* Unregister a resource.
|
|
401
|
+
* Note: Pending requests for this resource will fail.
|
|
402
|
+
*/
|
|
403
|
+
unregister(resource: string): void;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* @module @kb-labs/core-resource-broker/queue/priority-queue
|
|
408
|
+
* Priority queue implementation with three levels: high, normal, low.
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Priority queue with three priority levels.
|
|
413
|
+
*
|
|
414
|
+
* - High priority items are always dequeued first
|
|
415
|
+
* - Within the same priority, items are dequeued FIFO
|
|
416
|
+
* - Supports peeking without removing
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
* ```typescript
|
|
420
|
+
* const queue = new PriorityQueue();
|
|
421
|
+
*
|
|
422
|
+
* queue.enqueue(item1); // normal priority
|
|
423
|
+
* queue.enqueue(item2); // high priority
|
|
424
|
+
*
|
|
425
|
+
* const next = queue.dequeue(); // returns item2 (high priority)
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
declare class PriorityQueue {
|
|
429
|
+
private high;
|
|
430
|
+
private normal;
|
|
431
|
+
private low;
|
|
432
|
+
/**
|
|
433
|
+
* Add an item to the queue.
|
|
434
|
+
*
|
|
435
|
+
* @param item - Queue item to add
|
|
436
|
+
*/
|
|
437
|
+
enqueue(item: QueueItem): void;
|
|
438
|
+
/**
|
|
439
|
+
* Remove and return the highest priority item.
|
|
440
|
+
*
|
|
441
|
+
* @returns The next item or undefined if queue is empty
|
|
442
|
+
*/
|
|
443
|
+
dequeue(): QueueItem | undefined;
|
|
444
|
+
/**
|
|
445
|
+
* Peek at the highest priority item without removing it.
|
|
446
|
+
*
|
|
447
|
+
* @returns The next item or undefined if queue is empty
|
|
448
|
+
*/
|
|
449
|
+
peek(): QueueItem | undefined;
|
|
450
|
+
/**
|
|
451
|
+
* Get total queue size.
|
|
452
|
+
*/
|
|
453
|
+
size(): number;
|
|
454
|
+
/**
|
|
455
|
+
* Get queue size by priority.
|
|
456
|
+
*/
|
|
457
|
+
sizeByPriority(): {
|
|
458
|
+
high: number;
|
|
459
|
+
normal: number;
|
|
460
|
+
low: number;
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Check if queue is empty.
|
|
464
|
+
*/
|
|
465
|
+
isEmpty(): boolean;
|
|
466
|
+
/**
|
|
467
|
+
* Clear all items from the queue.
|
|
468
|
+
*
|
|
469
|
+
* @returns All removed items (for cleanup/rejection)
|
|
470
|
+
*/
|
|
471
|
+
clear(): QueueItem[];
|
|
472
|
+
/**
|
|
473
|
+
* Remove a specific item by request ID.
|
|
474
|
+
*
|
|
475
|
+
* @param requestId - ID of the request to remove
|
|
476
|
+
* @returns The removed item or undefined if not found
|
|
477
|
+
*/
|
|
478
|
+
remove(requestId: string): QueueItem | undefined;
|
|
479
|
+
/**
|
|
480
|
+
* Get all items for a specific resource.
|
|
481
|
+
*
|
|
482
|
+
* @param resource - Resource identifier
|
|
483
|
+
* @returns Items matching the resource
|
|
484
|
+
*/
|
|
485
|
+
getByResource(resource: string): QueueItem[];
|
|
486
|
+
/**
|
|
487
|
+
* Get queue size for a specific resource.
|
|
488
|
+
*
|
|
489
|
+
* @param resource - Resource identifier
|
|
490
|
+
*/
|
|
491
|
+
sizeByResource(resource: string): number;
|
|
492
|
+
/**
|
|
493
|
+
* Iterate over all items (for inspection, not removal).
|
|
494
|
+
*/
|
|
495
|
+
[Symbol.iterator](): Iterator<QueueItem>;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @module @kb-labs/core-resource-broker/rate-limit/in-memory-backend
|
|
500
|
+
* In-memory implementation of RateLimitBackend for single-process deployments.
|
|
501
|
+
*/
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* In-memory rate limit backend.
|
|
505
|
+
*
|
|
506
|
+
* Uses sliding window approach for TPM/RPM/RPS tracking.
|
|
507
|
+
* Suitable for single-process deployments.
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* const backend = new InMemoryRateLimitBackend();
|
|
512
|
+
*
|
|
513
|
+
* const result = await backend.acquire('llm', 1000, {
|
|
514
|
+
* tokensPerMinute: 100000,
|
|
515
|
+
* requestsPerMinute: 1000,
|
|
516
|
+
* });
|
|
517
|
+
*
|
|
518
|
+
* if (result.allowed) {
|
|
519
|
+
* // Execute request
|
|
520
|
+
* await backend.release('llm');
|
|
521
|
+
* } else {
|
|
522
|
+
* // Wait and retry
|
|
523
|
+
* await sleep(result.waitTimeMs);
|
|
524
|
+
* }
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
declare class InMemoryRateLimitBackend implements RateLimitBackend {
|
|
528
|
+
private states;
|
|
529
|
+
/**
|
|
530
|
+
* Get or create state for a resource.
|
|
531
|
+
*/
|
|
532
|
+
private getState;
|
|
533
|
+
/**
|
|
534
|
+
* Reset windows if time has passed.
|
|
535
|
+
*/
|
|
536
|
+
private resetWindowsIfNeeded;
|
|
537
|
+
/**
|
|
538
|
+
* Check if all limits allow proceeding.
|
|
539
|
+
*/
|
|
540
|
+
private checkLimits;
|
|
541
|
+
/**
|
|
542
|
+
* @inheritdoc
|
|
543
|
+
*/
|
|
544
|
+
acquire(resource: string, tokens: number, config: RateLimitConfig): Promise<AcquireResult>;
|
|
545
|
+
/**
|
|
546
|
+
* @inheritdoc
|
|
547
|
+
*/
|
|
548
|
+
release(resource: string): Promise<void>;
|
|
549
|
+
/**
|
|
550
|
+
* @inheritdoc
|
|
551
|
+
*/
|
|
552
|
+
getStats(resource: string): Promise<RateLimitStats>;
|
|
553
|
+
/**
|
|
554
|
+
* @inheritdoc
|
|
555
|
+
*/
|
|
556
|
+
reset(resource: string): Promise<void>;
|
|
557
|
+
/**
|
|
558
|
+
* Reset all resources.
|
|
559
|
+
*/
|
|
560
|
+
resetAll(): void;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* @module @kb-labs/core-resource-broker/rate-limit/state-broker-backend
|
|
565
|
+
* Distributed rate limit backend using StateBroker.
|
|
566
|
+
*
|
|
567
|
+
* Enables horizontal scaling by storing rate counters in a shared StateBroker
|
|
568
|
+
* (HTTP daemon or future Redis backend).
|
|
569
|
+
*/
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Distributed rate limit backend using StateBroker.
|
|
573
|
+
*
|
|
574
|
+
* Key patterns:
|
|
575
|
+
* - `ratelimit:{resource}:minute:{YYYY-MM-DDTHH:MM}` - Minute window counters
|
|
576
|
+
* - `ratelimit:{resource}:second:{YYYY-MM-DDTHH:MM:SS}` - Second window counters
|
|
577
|
+
* - `ratelimit:{resource}:active` - Active concurrent requests
|
|
578
|
+
* - `ratelimit:{resource}:stats` - Cumulative statistics
|
|
579
|
+
*
|
|
580
|
+
* TTL strategy:
|
|
581
|
+
* - Minute windows: 120s TTL (allows for clock skew)
|
|
582
|
+
* - Second windows: 10s TTL
|
|
583
|
+
* - Active counter: No TTL (managed explicitly)
|
|
584
|
+
* - Stats: No TTL (persisted)
|
|
585
|
+
*
|
|
586
|
+
* @example
|
|
587
|
+
* ```typescript
|
|
588
|
+
* import { createStateBroker } from '@kb-labs/core-state-broker';
|
|
589
|
+
*
|
|
590
|
+
* const broker = createStateBroker({ backend: 'http', url: 'http://localhost:7777' });
|
|
591
|
+
* const backend = new StateBrokerRateLimitBackend(broker);
|
|
592
|
+
*
|
|
593
|
+
* // Now rate limits are coordinated across all processes using the same daemon
|
|
594
|
+
* ```
|
|
595
|
+
*/
|
|
596
|
+
declare class StateBrokerRateLimitBackend implements RateLimitBackend {
|
|
597
|
+
private broker;
|
|
598
|
+
constructor(broker: StateBroker);
|
|
599
|
+
/**
|
|
600
|
+
* Get current minute window key.
|
|
601
|
+
*/
|
|
602
|
+
private getMinuteKey;
|
|
603
|
+
/**
|
|
604
|
+
* Get current second window key.
|
|
605
|
+
*/
|
|
606
|
+
private getSecondKey;
|
|
607
|
+
/**
|
|
608
|
+
* Get active requests key.
|
|
609
|
+
*/
|
|
610
|
+
private getActiveKey;
|
|
611
|
+
/**
|
|
612
|
+
* Get stats key.
|
|
613
|
+
*/
|
|
614
|
+
private getStatsKey;
|
|
615
|
+
/**
|
|
616
|
+
* Get or initialize window state.
|
|
617
|
+
*/
|
|
618
|
+
private getWindowState;
|
|
619
|
+
/**
|
|
620
|
+
* Get or initialize stats.
|
|
621
|
+
*/
|
|
622
|
+
private getCumulativeStats;
|
|
623
|
+
/**
|
|
624
|
+
* @inheritdoc
|
|
625
|
+
*/
|
|
626
|
+
acquire(resource: string, tokens: number, config: RateLimitConfig): Promise<AcquireResult>;
|
|
627
|
+
/**
|
|
628
|
+
* @inheritdoc
|
|
629
|
+
*/
|
|
630
|
+
release(resource: string): Promise<void>;
|
|
631
|
+
/**
|
|
632
|
+
* @inheritdoc
|
|
633
|
+
*/
|
|
634
|
+
getStats(resource: string): Promise<RateLimitStats>;
|
|
635
|
+
/**
|
|
636
|
+
* @inheritdoc
|
|
637
|
+
*/
|
|
638
|
+
reset(resource: string): Promise<void>;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* @module @kb-labs/core-resource-broker/rate-limit/presets
|
|
643
|
+
* Pre-configured rate limits for common providers.
|
|
644
|
+
*/
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Pre-configured rate limits for common providers.
|
|
648
|
+
*/
|
|
649
|
+
declare const RATE_LIMIT_PRESETS: {
|
|
650
|
+
/**
|
|
651
|
+
* OpenAI Tier 1 (paid accounts, entry level)
|
|
652
|
+
* Updated Nov 2024: Tier 1 now has 1M TPM for embeddings
|
|
653
|
+
*/
|
|
654
|
+
readonly 'openai-tier-1': {
|
|
655
|
+
tokensPerMinute: number;
|
|
656
|
+
requestsPerMinute: number;
|
|
657
|
+
maxTokensPerRequest: number;
|
|
658
|
+
safetyMargin: number;
|
|
659
|
+
};
|
|
660
|
+
/**
|
|
661
|
+
* OpenAI Tier 2 (after $50+ spent)
|
|
662
|
+
*/
|
|
663
|
+
readonly 'openai-tier-2': {
|
|
664
|
+
tokensPerMinute: number;
|
|
665
|
+
requestsPerMinute: number;
|
|
666
|
+
maxTokensPerRequest: number;
|
|
667
|
+
safetyMargin: number;
|
|
668
|
+
};
|
|
669
|
+
/**
|
|
670
|
+
* OpenAI Tier 3
|
|
671
|
+
*/
|
|
672
|
+
readonly 'openai-tier-3': {
|
|
673
|
+
tokensPerMinute: number;
|
|
674
|
+
requestsPerMinute: number;
|
|
675
|
+
maxTokensPerRequest: number;
|
|
676
|
+
safetyMargin: number;
|
|
677
|
+
};
|
|
678
|
+
/**
|
|
679
|
+
* OpenAI Tier 4
|
|
680
|
+
*/
|
|
681
|
+
readonly 'openai-tier-4': {
|
|
682
|
+
tokensPerMinute: number;
|
|
683
|
+
requestsPerMinute: number;
|
|
684
|
+
maxTokensPerRequest: number;
|
|
685
|
+
safetyMargin: number;
|
|
686
|
+
};
|
|
687
|
+
/**
|
|
688
|
+
* OpenAI Tier 5 (enterprise)
|
|
689
|
+
*/
|
|
690
|
+
readonly 'openai-tier-5': {
|
|
691
|
+
tokensPerMinute: number;
|
|
692
|
+
requestsPerMinute: number;
|
|
693
|
+
maxTokensPerRequest: number;
|
|
694
|
+
safetyMargin: number;
|
|
695
|
+
};
|
|
696
|
+
/**
|
|
697
|
+
* OpenAI GPT-4 specific limits (more restrictive)
|
|
698
|
+
*/
|
|
699
|
+
readonly 'openai-gpt4': {
|
|
700
|
+
tokensPerMinute: number;
|
|
701
|
+
requestsPerMinute: number;
|
|
702
|
+
maxTokensPerRequest: number;
|
|
703
|
+
safetyMargin: number;
|
|
704
|
+
};
|
|
705
|
+
/**
|
|
706
|
+
* Anthropic Tier 1 (default)
|
|
707
|
+
*/
|
|
708
|
+
readonly 'anthropic-tier-1': {
|
|
709
|
+
tokensPerMinute: number;
|
|
710
|
+
requestsPerMinute: number;
|
|
711
|
+
maxTokensPerRequest: number;
|
|
712
|
+
safetyMargin: number;
|
|
713
|
+
};
|
|
714
|
+
/**
|
|
715
|
+
* Anthropic Tier 2
|
|
716
|
+
*/
|
|
717
|
+
readonly 'anthropic-tier-2': {
|
|
718
|
+
tokensPerMinute: number;
|
|
719
|
+
requestsPerMinute: number;
|
|
720
|
+
maxTokensPerRequest: number;
|
|
721
|
+
safetyMargin: number;
|
|
722
|
+
};
|
|
723
|
+
/**
|
|
724
|
+
* Anthropic Tier 3
|
|
725
|
+
*/
|
|
726
|
+
readonly 'anthropic-tier-3': {
|
|
727
|
+
tokensPerMinute: number;
|
|
728
|
+
requestsPerMinute: number;
|
|
729
|
+
maxTokensPerRequest: number;
|
|
730
|
+
safetyMargin: number;
|
|
731
|
+
};
|
|
732
|
+
/**
|
|
733
|
+
* Anthropic Tier 4
|
|
734
|
+
*/
|
|
735
|
+
readonly 'anthropic-tier-4': {
|
|
736
|
+
tokensPerMinute: number;
|
|
737
|
+
requestsPerMinute: number;
|
|
738
|
+
maxTokensPerRequest: number;
|
|
739
|
+
safetyMargin: number;
|
|
740
|
+
};
|
|
741
|
+
/**
|
|
742
|
+
* Sber GigaChat API
|
|
743
|
+
* Conservative limits for typical access
|
|
744
|
+
*/
|
|
745
|
+
readonly 'sber-gigachat': {
|
|
746
|
+
requestsPerMinute: number;
|
|
747
|
+
requestsPerSecond: number;
|
|
748
|
+
safetyMargin: number;
|
|
749
|
+
};
|
|
750
|
+
/**
|
|
751
|
+
* Yandex GPT API
|
|
752
|
+
*/
|
|
753
|
+
readonly 'yandex-gpt': {
|
|
754
|
+
requestsPerMinute: number;
|
|
755
|
+
requestsPerSecond: number;
|
|
756
|
+
safetyMargin: number;
|
|
757
|
+
};
|
|
758
|
+
/**
|
|
759
|
+
* Local Ollama
|
|
760
|
+
* No external rate limits, only GPU concurrency
|
|
761
|
+
*/
|
|
762
|
+
readonly 'ollama-local': {
|
|
763
|
+
maxConcurrentRequests: number;
|
|
764
|
+
};
|
|
765
|
+
/**
|
|
766
|
+
* Self-hosted vLLM
|
|
767
|
+
*/
|
|
768
|
+
readonly 'vllm-local': {
|
|
769
|
+
maxConcurrentRequests: number;
|
|
770
|
+
requestsPerSecond: number;
|
|
771
|
+
};
|
|
772
|
+
/**
|
|
773
|
+
* Self-hosted text-embeddings-inference
|
|
774
|
+
*/
|
|
775
|
+
readonly 'tei-local': {
|
|
776
|
+
maxConcurrentRequests: number;
|
|
777
|
+
};
|
|
778
|
+
/**
|
|
779
|
+
* No rate limiting (for testing or unlimited APIs)
|
|
780
|
+
*/
|
|
781
|
+
readonly unlimited: {};
|
|
782
|
+
/**
|
|
783
|
+
* Very conservative (for debugging rate limit issues)
|
|
784
|
+
*/
|
|
785
|
+
readonly debug: {
|
|
786
|
+
tokensPerMinute: number;
|
|
787
|
+
requestsPerMinute: number;
|
|
788
|
+
maxConcurrentRequests: number;
|
|
789
|
+
safetyMargin: number;
|
|
790
|
+
};
|
|
791
|
+
};
|
|
792
|
+
type RateLimitPreset = keyof typeof RATE_LIMIT_PRESETS;
|
|
793
|
+
/**
|
|
794
|
+
* Get rate limit config from preset name or custom config.
|
|
795
|
+
*
|
|
796
|
+
* @param configOrPreset - Config object or preset name
|
|
797
|
+
* @returns Resolved rate limit configuration
|
|
798
|
+
*
|
|
799
|
+
* @example
|
|
800
|
+
* ```typescript
|
|
801
|
+
* // Use preset
|
|
802
|
+
* const config = getRateLimitConfig('openai-tier-2');
|
|
803
|
+
*
|
|
804
|
+
* // Use custom config
|
|
805
|
+
* const config = getRateLimitConfig({ tokensPerMinute: 100000 });
|
|
806
|
+
*
|
|
807
|
+
* // Default (openai-tier-2)
|
|
808
|
+
* const config = getRateLimitConfig();
|
|
809
|
+
* ```
|
|
810
|
+
*/
|
|
811
|
+
declare function getRateLimitConfig(configOrPreset?: RateLimitConfig | RateLimitPreset | string): RateLimitConfig;
|
|
812
|
+
/**
|
|
813
|
+
* Estimate tokens for a text (rough approximation).
|
|
814
|
+
* Uses ~4 characters per token as a conservative estimate.
|
|
815
|
+
*
|
|
816
|
+
* @param text - Text to estimate
|
|
817
|
+
* @returns Estimated token count
|
|
818
|
+
*/
|
|
819
|
+
declare function estimateTokens(text: string): number;
|
|
820
|
+
/**
|
|
821
|
+
* Estimate tokens for multiple texts.
|
|
822
|
+
*
|
|
823
|
+
* @param texts - Array of texts
|
|
824
|
+
* @returns Total estimated token count
|
|
825
|
+
*/
|
|
826
|
+
declare function estimateBatchTokens(texts: string[]): number;
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* @module @kb-labs/core-resource-broker/retry/error-classifier
|
|
830
|
+
* Error classification for retry logic.
|
|
831
|
+
*/
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Classify an error for retry decision.
|
|
835
|
+
*
|
|
836
|
+
* @param error - Error to classify
|
|
837
|
+
* @returns Error type classification
|
|
838
|
+
*/
|
|
839
|
+
declare function classifyError(error: unknown): ErrorType;
|
|
840
|
+
/**
|
|
841
|
+
* Check if an error is a rate limit error (429).
|
|
842
|
+
*/
|
|
843
|
+
declare function isRateLimitError(error: unknown): boolean;
|
|
844
|
+
/**
|
|
845
|
+
* Check if an error is retryable.
|
|
846
|
+
*
|
|
847
|
+
* @param error - Error to check
|
|
848
|
+
* @param retryableTypes - Types that should be retried
|
|
849
|
+
*/
|
|
850
|
+
declare function isRetryableError(error: unknown, retryableTypes?: ErrorType[]): boolean;
|
|
851
|
+
/**
|
|
852
|
+
* Extract retry-after hint from error if available.
|
|
853
|
+
*
|
|
854
|
+
* @param error - Error to extract hint from
|
|
855
|
+
* @returns Milliseconds to wait, or undefined
|
|
856
|
+
*/
|
|
857
|
+
declare function extractRetryAfter(error: unknown): number | undefined;
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* @module @kb-labs/core-resource-broker/retry/retry-strategy
|
|
861
|
+
* Exponential backoff retry strategy with jitter.
|
|
862
|
+
*/
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Result of a retry decision.
|
|
866
|
+
*/
|
|
867
|
+
interface RetryDecision {
|
|
868
|
+
/** Whether to retry */
|
|
869
|
+
shouldRetry: boolean;
|
|
870
|
+
/** Delay before retry (ms) */
|
|
871
|
+
delayMs: number;
|
|
872
|
+
/** Error classification */
|
|
873
|
+
errorType: ErrorType;
|
|
874
|
+
/** Current attempt number (0-indexed) */
|
|
875
|
+
attempt: number;
|
|
876
|
+
/** Maximum attempts allowed */
|
|
877
|
+
maxAttempts: number;
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Calculate delay with exponential backoff and jitter.
|
|
881
|
+
*
|
|
882
|
+
* Formula: min(maxDelay, baseDelay * 2^attempt) * (1 + random * jitter)
|
|
883
|
+
*
|
|
884
|
+
* @param attempt - Current attempt (0-indexed)
|
|
885
|
+
* @param config - Retry configuration
|
|
886
|
+
* @param retryAfterHint - Optional retry-after hint from error (ms)
|
|
887
|
+
* @returns Delay in milliseconds
|
|
888
|
+
*/
|
|
889
|
+
declare function calculateBackoffDelay(attempt: number, config: RetryConfig, retryAfterHint?: number): number;
|
|
890
|
+
/**
|
|
891
|
+
* Decide whether to retry based on error and attempt count.
|
|
892
|
+
*
|
|
893
|
+
* @param error - The error that occurred
|
|
894
|
+
* @param attempt - Current attempt (0-indexed)
|
|
895
|
+
* @param config - Retry configuration
|
|
896
|
+
* @returns Retry decision with delay
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* ```typescript
|
|
900
|
+
* const decision = shouldRetry(error, 0, config);
|
|
901
|
+
*
|
|
902
|
+
* if (decision.shouldRetry) {
|
|
903
|
+
* await sleep(decision.delayMs);
|
|
904
|
+
* // retry...
|
|
905
|
+
* } else {
|
|
906
|
+
* throw error;
|
|
907
|
+
* }
|
|
908
|
+
* ```
|
|
909
|
+
*/
|
|
910
|
+
declare function shouldRetry(error: unknown, attempt: number, config?: Partial<RetryConfig>): RetryDecision;
|
|
911
|
+
/**
|
|
912
|
+
* Execute a function with retry logic.
|
|
913
|
+
*
|
|
914
|
+
* @param fn - Function to execute
|
|
915
|
+
* @param config - Retry configuration
|
|
916
|
+
* @returns Result of the function
|
|
917
|
+
* @throws Last error if all retries exhausted
|
|
918
|
+
*
|
|
919
|
+
* @example
|
|
920
|
+
* ```typescript
|
|
921
|
+
* const result = await withRetry(
|
|
922
|
+
* async () => {
|
|
923
|
+
* return await llm.complete(prompt);
|
|
924
|
+
* },
|
|
925
|
+
* { maxRetries: 3, baseDelay: 1000 }
|
|
926
|
+
* );
|
|
927
|
+
* ```
|
|
928
|
+
*/
|
|
929
|
+
declare function withRetry<T>(fn: () => Promise<T>, config?: Partial<RetryConfig>): Promise<{
|
|
930
|
+
result: T;
|
|
931
|
+
attempts: number;
|
|
932
|
+
}>;
|
|
933
|
+
/**
|
|
934
|
+
* Sleep for a specified duration.
|
|
935
|
+
*
|
|
936
|
+
* @param ms - Milliseconds to sleep
|
|
937
|
+
*/
|
|
938
|
+
declare function sleep(ms: number): Promise<void>;
|
|
939
|
+
/**
|
|
940
|
+
* Create a retry configuration for rate-limited APIs.
|
|
941
|
+
*
|
|
942
|
+
* @param maxRetries - Maximum retry attempts (default: 5)
|
|
943
|
+
* @returns Retry config optimized for rate limits
|
|
944
|
+
*/
|
|
945
|
+
declare function createRateLimitRetryConfig(maxRetries?: number): RetryConfig;
|
|
946
|
+
/**
|
|
947
|
+
* Create a retry configuration for quick operations.
|
|
948
|
+
*
|
|
949
|
+
* @param maxRetries - Maximum retry attempts (default: 3)
|
|
950
|
+
* @returns Retry config with fast retries
|
|
951
|
+
*/
|
|
952
|
+
declare function createQuickRetryConfig(maxRetries?: number): RetryConfig;
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* @module @kb-labs/core-resource-broker/wrappers/queued-llm
|
|
956
|
+
* QueuedLLM - ILLM wrapper that routes requests through ResourceBroker.
|
|
957
|
+
*/
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Extended LLM options with priority.
|
|
961
|
+
*/
|
|
962
|
+
interface QueuedLLMOptions extends LLMOptions {
|
|
963
|
+
/** Request priority (default: 'normal') */
|
|
964
|
+
priority?: ResourcePriority;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* ILLM wrapper that routes requests through ResourceBroker.
|
|
968
|
+
*
|
|
969
|
+
* Features:
|
|
970
|
+
* - Transparent integration (implements ILLM interface)
|
|
971
|
+
* - Automatic token estimation for rate limiting
|
|
972
|
+
* - Priority support for different use cases
|
|
973
|
+
* - Retry and rate limiting handled by broker
|
|
974
|
+
*
|
|
975
|
+
* Note: stream() bypasses the queue for real-time UX.
|
|
976
|
+
*
|
|
977
|
+
* @example
|
|
978
|
+
* ```typescript
|
|
979
|
+
* const queuedLLM = new QueuedLLM(broker, realLLM);
|
|
980
|
+
*
|
|
981
|
+
* // Normal request (goes through queue)
|
|
982
|
+
* const response = await queuedLLM.complete(prompt);
|
|
983
|
+
*
|
|
984
|
+
* // High priority request
|
|
985
|
+
* const response = await queuedLLM.complete(prompt, { priority: 'high' });
|
|
986
|
+
*
|
|
987
|
+
* // Stream (bypasses queue for real-time)
|
|
988
|
+
* for await (const chunk of queuedLLM.stream(prompt)) {
|
|
989
|
+
* process.stdout.write(chunk);
|
|
990
|
+
* }
|
|
991
|
+
* ```
|
|
992
|
+
*/
|
|
993
|
+
declare class QueuedLLM implements ILLM {
|
|
994
|
+
private broker;
|
|
995
|
+
private realLLM;
|
|
996
|
+
constructor(broker: IResourceBroker, realLLM: ILLM);
|
|
997
|
+
/**
|
|
998
|
+
* Generate a completion through the queue.
|
|
999
|
+
*
|
|
1000
|
+
* @param prompt - Text prompt
|
|
1001
|
+
* @param options - Optional generation options with priority
|
|
1002
|
+
* @returns LLM response
|
|
1003
|
+
* @throws Error if request fails after all retries
|
|
1004
|
+
*/
|
|
1005
|
+
complete(prompt: string, options?: QueuedLLMOptions): Promise<LLMResponse>;
|
|
1006
|
+
getProtocolCapabilities(): Promise<LLMProtocolCapabilities>;
|
|
1007
|
+
/**
|
|
1008
|
+
* Stream a completion (bypasses queue for real-time UX).
|
|
1009
|
+
*
|
|
1010
|
+
* Streaming is passed through directly to the underlying LLM
|
|
1011
|
+
* because:
|
|
1012
|
+
* 1. Real-time user experience requires immediate response
|
|
1013
|
+
* 2. Token counting happens after streaming completes
|
|
1014
|
+
* 3. Rate limits are still enforced by the underlying adapter
|
|
1015
|
+
*
|
|
1016
|
+
* @param prompt - Text prompt
|
|
1017
|
+
* @param options - Optional generation options
|
|
1018
|
+
* @returns Async iterable of text chunks
|
|
1019
|
+
*/
|
|
1020
|
+
stream(prompt: string, options?: LLMOptions): AsyncIterable<string>;
|
|
1021
|
+
/**
|
|
1022
|
+
* Chat with native tool calling support (proxies to underlying LLM).
|
|
1023
|
+
* Currently NOT queued - passes through directly for simplicity.
|
|
1024
|
+
* TODO: Add queueing support when needed.
|
|
1025
|
+
*/
|
|
1026
|
+
chatWithTools(messages: LLMMessage[], options: LLMToolCallOptions): Promise<LLMToolCallResponse>;
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Create a QueuedLLM wrapper.
|
|
1030
|
+
*
|
|
1031
|
+
* @param broker - ResourceBroker instance
|
|
1032
|
+
* @param llm - Real ILLM implementation
|
|
1033
|
+
* @returns Wrapped ILLM that routes through broker
|
|
1034
|
+
*/
|
|
1035
|
+
declare function createQueuedLLM(broker: IResourceBroker, llm: ILLM): QueuedLLM;
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* @module @kb-labs/core-resource-broker/wrappers/queued-embeddings
|
|
1039
|
+
* QueuedEmbeddings - IEmbeddings wrapper that routes requests through ResourceBroker.
|
|
1040
|
+
*/
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Options for queued embeddings operations.
|
|
1044
|
+
*/
|
|
1045
|
+
interface QueuedEmbeddingsOptions {
|
|
1046
|
+
/** Request priority (default: 'normal') */
|
|
1047
|
+
priority?: ResourcePriority;
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* IEmbeddings wrapper that routes requests through ResourceBroker.
|
|
1051
|
+
*
|
|
1052
|
+
* Features:
|
|
1053
|
+
* - Transparent integration (implements IEmbeddings interface)
|
|
1054
|
+
* - Automatic token estimation for rate limiting
|
|
1055
|
+
* - Batch operations with proper token accounting
|
|
1056
|
+
* - Priority support for different use cases
|
|
1057
|
+
*
|
|
1058
|
+
* @example
|
|
1059
|
+
* ```typescript
|
|
1060
|
+
* const queuedEmbeddings = new QueuedEmbeddings(broker, realEmbeddings);
|
|
1061
|
+
*
|
|
1062
|
+
* // Single embedding
|
|
1063
|
+
* const vector = await queuedEmbeddings.embed("Hello world");
|
|
1064
|
+
*
|
|
1065
|
+
* // Batch embedding
|
|
1066
|
+
* const vectors = await queuedEmbeddings.embedBatch(["Hello", "World"]);
|
|
1067
|
+
* ```
|
|
1068
|
+
*/
|
|
1069
|
+
declare class QueuedEmbeddings implements IEmbeddings {
|
|
1070
|
+
private broker;
|
|
1071
|
+
private realEmbeddings;
|
|
1072
|
+
private _priority;
|
|
1073
|
+
constructor(broker: IResourceBroker, realEmbeddings: IEmbeddings);
|
|
1074
|
+
/**
|
|
1075
|
+
* Get embedding dimensions from the underlying implementation.
|
|
1076
|
+
*/
|
|
1077
|
+
get dimensions(): number;
|
|
1078
|
+
/**
|
|
1079
|
+
* Set default priority for subsequent operations.
|
|
1080
|
+
*
|
|
1081
|
+
* @param priority - Priority level
|
|
1082
|
+
* @returns this for chaining
|
|
1083
|
+
*/
|
|
1084
|
+
withPriority(priority: ResourcePriority): this;
|
|
1085
|
+
/**
|
|
1086
|
+
* Generate embedding vector for a single text through the queue.
|
|
1087
|
+
*
|
|
1088
|
+
* @param text - Input text
|
|
1089
|
+
* @returns Embedding vector
|
|
1090
|
+
* @throws Error if request fails after all retries
|
|
1091
|
+
*/
|
|
1092
|
+
embed(text: string): Promise<number[]>;
|
|
1093
|
+
/**
|
|
1094
|
+
* Generate embedding vectors for multiple texts through the queue.
|
|
1095
|
+
*
|
|
1096
|
+
* @param texts - Array of input texts
|
|
1097
|
+
* @returns Array of embedding vectors
|
|
1098
|
+
* @throws Error if request fails after all retries
|
|
1099
|
+
*/
|
|
1100
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
1101
|
+
/**
|
|
1102
|
+
* Get the dimensions of the embeddings.
|
|
1103
|
+
* This method is needed for IPC/Unix Socket transport to access the dimensions property.
|
|
1104
|
+
*/
|
|
1105
|
+
getDimensions(): Promise<number>;
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Create a QueuedEmbeddings wrapper.
|
|
1109
|
+
*
|
|
1110
|
+
* @param broker - ResourceBroker instance
|
|
1111
|
+
* @param embeddings - Real IEmbeddings implementation
|
|
1112
|
+
* @returns Wrapped IEmbeddings that routes through broker
|
|
1113
|
+
*/
|
|
1114
|
+
declare function createQueuedEmbeddings(broker: IResourceBroker, embeddings: IEmbeddings): QueuedEmbeddings;
|
|
1115
|
+
|
|
1116
|
+
/**
|
|
1117
|
+
* @module @kb-labs/core-resource-broker/wrappers/queued-vector-store
|
|
1118
|
+
* QueuedVectorStore - IVectorStore wrapper that routes requests through ResourceBroker.
|
|
1119
|
+
*/
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* Options for queued vector store operations.
|
|
1123
|
+
*/
|
|
1124
|
+
interface QueuedVectorStoreOptions {
|
|
1125
|
+
/** Request priority (default: 'normal') */
|
|
1126
|
+
priority?: ResourcePriority;
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* IVectorStore wrapper that routes requests through ResourceBroker.
|
|
1130
|
+
*
|
|
1131
|
+
* Features:
|
|
1132
|
+
* - Transparent integration (implements IVectorStore interface)
|
|
1133
|
+
* - Rate limiting for batch operations
|
|
1134
|
+
* - Priority support for different use cases
|
|
1135
|
+
* - Search operations prioritized over bulk upserts
|
|
1136
|
+
*
|
|
1137
|
+
* @example
|
|
1138
|
+
* ```typescript
|
|
1139
|
+
* const queuedVectorStore = new QueuedVectorStore(broker, realVectorStore);
|
|
1140
|
+
*
|
|
1141
|
+
* // Search (typically high priority)
|
|
1142
|
+
* const results = await queuedVectorStore.search(queryVector, 10);
|
|
1143
|
+
*
|
|
1144
|
+
* // Bulk upsert (typically normal/low priority)
|
|
1145
|
+
* await queuedVectorStore.upsert(vectors);
|
|
1146
|
+
* ```
|
|
1147
|
+
*/
|
|
1148
|
+
declare class QueuedVectorStore implements IVectorStore {
|
|
1149
|
+
private broker;
|
|
1150
|
+
private realVectorStore;
|
|
1151
|
+
private _priority;
|
|
1152
|
+
constructor(broker: IResourceBroker, realVectorStore: IVectorStore);
|
|
1153
|
+
/**
|
|
1154
|
+
* Set default priority for subsequent operations.
|
|
1155
|
+
*
|
|
1156
|
+
* @param priority - Priority level
|
|
1157
|
+
* @returns this for chaining
|
|
1158
|
+
*/
|
|
1159
|
+
withPriority(priority: ResourcePriority): this;
|
|
1160
|
+
/**
|
|
1161
|
+
* Search for similar vectors through the queue.
|
|
1162
|
+
*
|
|
1163
|
+
* @param query - Query embedding vector
|
|
1164
|
+
* @param limit - Maximum number of results
|
|
1165
|
+
* @param filter - Optional metadata filter
|
|
1166
|
+
* @returns Search results
|
|
1167
|
+
* @throws Error if request fails after all retries
|
|
1168
|
+
*/
|
|
1169
|
+
search(query: number[], limit: number, filter?: VectorFilter): Promise<VectorSearchResult[]>;
|
|
1170
|
+
/**
|
|
1171
|
+
* Upsert vectors through the queue.
|
|
1172
|
+
*
|
|
1173
|
+
* @param vectors - Array of vector records to upsert
|
|
1174
|
+
* @throws Error if request fails after all retries
|
|
1175
|
+
*/
|
|
1176
|
+
upsert(vectors: VectorRecord[]): Promise<void>;
|
|
1177
|
+
/**
|
|
1178
|
+
* Delete vectors through the queue.
|
|
1179
|
+
*
|
|
1180
|
+
* @param ids - Array of vector IDs to delete
|
|
1181
|
+
* @throws Error if request fails after all retries
|
|
1182
|
+
*/
|
|
1183
|
+
delete(ids: string[]): Promise<void>;
|
|
1184
|
+
/**
|
|
1185
|
+
* Get total count of vectors through the queue.
|
|
1186
|
+
*
|
|
1187
|
+
* @returns Vector count
|
|
1188
|
+
* @throws Error if request fails after all retries
|
|
1189
|
+
*/
|
|
1190
|
+
count(): Promise<number>;
|
|
1191
|
+
/**
|
|
1192
|
+
* Get vectors by IDs through the queue (if supported).
|
|
1193
|
+
*
|
|
1194
|
+
* @param ids - Array of vector IDs to retrieve
|
|
1195
|
+
* @returns Array of vector records
|
|
1196
|
+
* @throws Error if request fails or method not supported
|
|
1197
|
+
*/
|
|
1198
|
+
get(ids: string[]): Promise<VectorRecord[]>;
|
|
1199
|
+
/**
|
|
1200
|
+
* Query vectors by filter through the queue (if supported).
|
|
1201
|
+
*
|
|
1202
|
+
* @param filter - Metadata filter to apply
|
|
1203
|
+
* @returns Array of matching vector records
|
|
1204
|
+
* @throws Error if request fails or method not supported
|
|
1205
|
+
*/
|
|
1206
|
+
query(filter: VectorFilter): Promise<VectorRecord[]>;
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* Create a QueuedVectorStore wrapper.
|
|
1210
|
+
*
|
|
1211
|
+
* @param broker - ResourceBroker instance
|
|
1212
|
+
* @param vectorStore - Real IVectorStore implementation
|
|
1213
|
+
* @returns Wrapped IVectorStore that routes through broker
|
|
1214
|
+
*/
|
|
1215
|
+
declare function createQueuedVectorStore(broker: IResourceBroker, vectorStore: IVectorStore): QueuedVectorStore;
|
|
1216
|
+
|
|
1217
|
+
export { type AcquireResult, DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RETRY_CONFIG, type ErrorType, type IResourceBroker, InMemoryRateLimitBackend, PriorityQueue, type QueueItem, QueuedEmbeddings, type QueuedEmbeddingsOptions, QueuedLLM, type QueuedLLMOptions, QueuedVectorStore, type QueuedVectorStoreOptions, RATE_LIMIT_PRESETS, type RateLimitBackend, type RateLimitConfig, type RateLimitPreset, type RateLimitStats, ResourceBroker, type ResourceBrokerStats, type ResourceConfig, type ResourceExecutor, type ResourcePriority, type ResourceRequest, type ResourceResponse, type ResourceStats, type RetryConfig, type RetryDecision, StateBrokerRateLimitBackend, calculateBackoffDelay, classifyError, createQueuedEmbeddings, createQueuedLLM, createQueuedVectorStore, createQuickRetryConfig, createRateLimitRetryConfig, estimateBatchTokens, estimateTokens, extractRetryAfter, getRateLimitConfig, isRateLimitError, isRetryableError, shouldRetry, sleep, withRetry };
|