@kb-labs/core-resource-broker 2.94.0 → 2.98.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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
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';
2
+ import { ILLM, LLMOptions, LLMResponse, LLMProtocolCapabilities, LLMMessage, LLMToolCallOptions, LLMToolCallResponse, IEmbeddings, IVectorStore, VectorFilter, VectorSearchResult, VectorRecord, INotifierChannel, NotificationCapability, NotificationEvent } from '@kb-labs/core-platform';
3
3
 
4
4
  /**
5
5
  * @module @kb-labs/core-resource-broker/types
@@ -240,9 +240,40 @@ interface ResourceStats {
240
240
  /** Average processing time (ms) */
241
241
  avgProcessingTime: number;
242
242
  }
243
+ /**
244
+ * Options for `IResourceBroker.tryAcquire`.
245
+ */
246
+ interface TryAcquireOptions {
247
+ /**
248
+ * Estimated tokens for this acquisition.
249
+ * Default: 0 — HTTP endpoints typically don't consume LLM tokens.
250
+ */
251
+ tokens?: number;
252
+ }
253
+ /**
254
+ * Result of `IResourceBroker.tryAcquire`. Extends `AcquireResult` with a
255
+ * caller-bound `release` handle.
256
+ *
257
+ * Contract:
258
+ * - When `allowed=true`, the caller MUST invoke `release()` once the work
259
+ * is done (typically in a `finally` block).
260
+ * - `release()` is idempotent: multiple calls are safe.
261
+ * - When `allowed=false`, `release()` is a no-op so callers can use the
262
+ * unconditional `try { ... } finally { result.release() }` pattern.
263
+ */
264
+ interface TryAcquireResult extends AcquireResult {
265
+ release: () => Promise<void>;
266
+ }
243
267
  /**
244
268
  * Main resource broker interface.
245
269
  * Coordinates queues, rate limiting, and execution for all resources.
270
+ *
271
+ * Supports two patterns:
272
+ * - **queue + execute** — `register` + `enqueue`. For LLM, embeddings, vector
273
+ * store calls where long, asynchronous work is queued and retried.
274
+ * - **check + reject** — `registerLimit` + `tryAcquire`. For HTTP endpoints
275
+ * (webhook routers, public APIs) that need an immediate accept/reject
276
+ * decision without queueing.
246
277
  */
247
278
  interface IResourceBroker {
248
279
  /**
@@ -252,6 +283,17 @@ interface IResourceBroker {
252
283
  * @param config - Resource configuration
253
284
  */
254
285
  register(resource: string, config: ResourceConfig): void;
286
+ /**
287
+ * Register a resource for limit-only usage (no executor, no queue).
288
+ *
289
+ * Use together with `tryAcquire` for HTTP-style "check + reject" pressure
290
+ * control. Calling `enqueue` against a limit-only resource resolves with
291
+ * `{ success: false, error }` — it does not throw.
292
+ *
293
+ * @param resource - Resource identifier
294
+ * @param rateLimits - Rate limit configuration or preset name
295
+ */
296
+ registerLimit(resource: string, rateLimits: RateLimitConfig | string): void;
255
297
  /**
256
298
  * Enqueue a request for execution.
257
299
  * Returns a promise that resolves when the request completes.
@@ -260,6 +302,21 @@ interface IResourceBroker {
260
302
  * @returns Response with result or error
261
303
  */
262
304
  enqueue<T>(request: Omit<ResourceRequest, 'id' | 'createdAt'>): Promise<ResourceResponse<T>>;
305
+ /**
306
+ * Atomically check and reserve rate-limit capacity without queueing.
307
+ * Returns immediately. Intended for HTTP endpoints that must accept or
308
+ * reject inbound requests synchronously.
309
+ *
310
+ * - On `allowed=true`, the caller MUST invoke `result.release()` once the
311
+ * request has been served.
312
+ * - On `allowed=false`, `result.release()` is a no-op.
313
+ * - Throws if the resource has not been registered (programming error).
314
+ * - Returns `{ allowed: false, release: noop }` after `shutdown()`.
315
+ *
316
+ * @param resource - Resource identifier
317
+ * @param opts - Acquisition options (e.g., estimated tokens)
318
+ */
319
+ tryAcquire(resource: string, opts?: TryAcquireOptions): Promise<TryAcquireResult>;
263
320
  /**
264
321
  * Get broker statistics.
265
322
  */
@@ -359,6 +416,13 @@ declare class ResourceBroker implements IResourceBroker {
359
416
  * @param config - Resource configuration including executor
360
417
  */
361
418
  register(resource: string, config: ResourceConfig): void;
419
+ /**
420
+ * Register a resource for limit-only usage (no executor, no queue).
421
+ *
422
+ * The resource can only be used via `tryAcquire`. Calls to `enqueue` on
423
+ * a limit-only resource resolve with `{ success: false, error }`.
424
+ */
425
+ registerLimit(resource: string, rateLimits: RateLimitConfig | string): void;
362
426
  /**
363
427
  * Enqueue a request for execution.
364
428
  *
@@ -366,6 +430,19 @@ declare class ResourceBroker implements IResourceBroker {
366
430
  * @returns Promise that resolves with response when execution completes
367
431
  */
368
432
  enqueue<T>(request: Omit<ResourceRequest, 'id' | 'createdAt'>): Promise<ResourceResponse<T>>;
433
+ /**
434
+ * Atomically check and reserve rate-limit capacity without queueing.
435
+ *
436
+ * Use for HTTP-style "check + reject" pressure control. On `allowed=true`,
437
+ * the caller MUST invoke `result.release()` once the work is done. On
438
+ * `allowed=false`, `release` is a no-op so callers can use the
439
+ * unconditional `try { ... } finally { result.release() }` pattern.
440
+ *
441
+ * Throws if the resource has not been registered (programming error,
442
+ * distinct from a rate-limit decision). Returns `{ allowed: false, release: noop }`
443
+ * after `shutdown()`.
444
+ */
445
+ tryAcquire(resource: string, opts?: TryAcquireOptions): Promise<TryAcquireResult>;
369
446
  /**
370
447
  * Process queue items continuously.
371
448
  */
@@ -1166,28 +1243,28 @@ declare class QueuedVectorStore implements IVectorStore {
1166
1243
  * @returns Search results
1167
1244
  * @throws Error if request fails after all retries
1168
1245
  */
1169
- search(query: number[], limit: number, filter?: VectorFilter): Promise<VectorSearchResult[]>;
1246
+ search(query: number[], limit: number, filter?: VectorFilter, namespace?: string): Promise<VectorSearchResult[]>;
1170
1247
  /**
1171
1248
  * Upsert vectors through the queue.
1172
1249
  *
1173
1250
  * @param vectors - Array of vector records to upsert
1174
1251
  * @throws Error if request fails after all retries
1175
1252
  */
1176
- upsert(vectors: VectorRecord[]): Promise<void>;
1253
+ upsert(vectors: VectorRecord[], namespace?: string): Promise<void>;
1177
1254
  /**
1178
1255
  * Delete vectors through the queue.
1179
1256
  *
1180
1257
  * @param ids - Array of vector IDs to delete
1181
1258
  * @throws Error if request fails after all retries
1182
1259
  */
1183
- delete(ids: string[]): Promise<void>;
1260
+ delete(ids: string[], namespace?: string): Promise<void>;
1184
1261
  /**
1185
1262
  * Get total count of vectors through the queue.
1186
1263
  *
1187
1264
  * @returns Vector count
1188
1265
  * @throws Error if request fails after all retries
1189
1266
  */
1190
- count(): Promise<number>;
1267
+ count(namespace?: string): Promise<number>;
1191
1268
  /**
1192
1269
  * Get vectors by IDs through the queue (if supported).
1193
1270
  *
@@ -1195,7 +1272,7 @@ declare class QueuedVectorStore implements IVectorStore {
1195
1272
  * @returns Array of vector records
1196
1273
  * @throws Error if request fails or method not supported
1197
1274
  */
1198
- get(ids: string[]): Promise<VectorRecord[]>;
1275
+ get(ids: string[], namespace?: string): Promise<VectorRecord[]>;
1199
1276
  /**
1200
1277
  * Query vectors by filter through the queue (if supported).
1201
1278
  *
@@ -1203,7 +1280,7 @@ declare class QueuedVectorStore implements IVectorStore {
1203
1280
  * @returns Array of matching vector records
1204
1281
  * @throws Error if request fails or method not supported
1205
1282
  */
1206
- query(filter: VectorFilter): Promise<VectorRecord[]>;
1283
+ query(filter: VectorFilter, namespace?: string): Promise<VectorRecord[]>;
1207
1284
  }
1208
1285
  /**
1209
1286
  * Create a QueuedVectorStore wrapper.
@@ -1214,4 +1291,23 @@ declare class QueuedVectorStore implements IVectorStore {
1214
1291
  */
1215
1292
  declare function createQueuedVectorStore(broker: IResourceBroker, vectorStore: IVectorStore): QueuedVectorStore;
1216
1293
 
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 };
1294
+ /**
1295
+ * @module @kb-labs/core-resource-broker/wrappers/queued-notifier-channel
1296
+ * QueuedNotifierChannel — INotifierChannel wrapper that routes send() through ResourceBroker.
1297
+ *
1298
+ * Provides rate-limiting, retry with exponential backoff, priority queue, and
1299
+ * distributed quota (via StateBroker) for free — same as QueuedLLM.
1300
+ */
1301
+
1302
+ declare class QueuedNotifierChannel implements INotifierChannel {
1303
+ private broker;
1304
+ private channel;
1305
+ constructor(broker: IResourceBroker, channel: INotifierChannel);
1306
+ get id(): string;
1307
+ get capabilities(): NotificationCapability[];
1308
+ isAvailable(): boolean;
1309
+ send(event: NotificationEvent): Promise<void>;
1310
+ }
1311
+ declare function createQueuedNotifierChannel(broker: IResourceBroker, channel: INotifierChannel): QueuedNotifierChannel;
1312
+
1313
+ export { type AcquireResult, DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RETRY_CONFIG, type ErrorType, type IResourceBroker, InMemoryRateLimitBackend, PriorityQueue, type QueueItem, QueuedEmbeddings, type QueuedEmbeddingsOptions, QueuedLLM, type QueuedLLMOptions, QueuedNotifierChannel, 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, type TryAcquireOptions, type TryAcquireResult, calculateBackoffDelay, classifyError, createQueuedEmbeddings, createQueuedLLM, createQueuedNotifierChannel, createQueuedVectorStore, createQuickRetryConfig, createRateLimitRetryConfig, estimateBatchTokens, estimateTokens, extractRetryAfter, getRateLimitConfig, isRateLimitError, isRetryableError, shouldRetry, sleep, withRetry };
package/dist/index.js CHANGED
@@ -539,6 +539,36 @@ var ResourceBroker = class {
539
539
  this.resources.set(resource, {
540
540
  config,
541
541
  rateLimits,
542
+ limitOnly: false,
543
+ stats: {
544
+ totalRequests: 0,
545
+ totalSuccess: 0,
546
+ totalErrors: 0,
547
+ totalWaitTime: 0,
548
+ totalProcessingTime: 0
549
+ }
550
+ });
551
+ this.activeProcessing.set(resource, 0);
552
+ }
553
+ /**
554
+ * Register a resource for limit-only usage (no executor, no queue).
555
+ *
556
+ * The resource can only be used via `tryAcquire`. Calls to `enqueue` on
557
+ * a limit-only resource resolve with `{ success: false, error }`.
558
+ */
559
+ registerLimit(resource, rateLimits) {
560
+ const resolved = typeof rateLimits === "string" ? getRateLimitConfig(rateLimits) : rateLimits;
561
+ this.resources.set(resource, {
562
+ config: {
563
+ rateLimits,
564
+ executor: async () => {
565
+ throw new Error(
566
+ `Cannot execute on limit-only resource '${resource}' (registered via registerLimit)`
567
+ );
568
+ }
569
+ },
570
+ rateLimits: resolved,
571
+ limitOnly: true,
542
572
  stats: {
543
573
  totalRequests: 0,
544
574
  totalSuccess: 0,
@@ -577,6 +607,18 @@ var ResourceBroker = class {
577
607
  totalTime: 0
578
608
  });
579
609
  }
610
+ if (registered.limitOnly) {
611
+ return Promise.resolve({
612
+ success: false,
613
+ error: new Error(
614
+ `Cannot enqueue on limit-only resource '${request.resource}' (registered via registerLimit \u2014 use tryAcquire instead)`
615
+ ),
616
+ retries: 0,
617
+ waitTime: 0,
618
+ processingTime: 0,
619
+ totalTime: 0
620
+ });
621
+ }
580
622
  const fullRequest = {
581
623
  ...request,
582
624
  id: randomUUID(),
@@ -596,6 +638,54 @@ var ResourceBroker = class {
596
638
  this.processQueue();
597
639
  });
598
640
  }
641
+ /**
642
+ * Atomically check and reserve rate-limit capacity without queueing.
643
+ *
644
+ * Use for HTTP-style "check + reject" pressure control. On `allowed=true`,
645
+ * the caller MUST invoke `result.release()` once the work is done. On
646
+ * `allowed=false`, `release` is a no-op so callers can use the
647
+ * unconditional `try { ... } finally { result.release() }` pattern.
648
+ *
649
+ * Throws if the resource has not been registered (programming error,
650
+ * distinct from a rate-limit decision). Returns `{ allowed: false, release: noop }`
651
+ * after `shutdown()`.
652
+ */
653
+ async tryAcquire(resource, opts) {
654
+ const noopRelease = async () => {
655
+ };
656
+ if (this.shuttingDown) {
657
+ return {
658
+ allowed: false,
659
+ release: noopRelease
660
+ };
661
+ }
662
+ const registered = this.resources.get(resource);
663
+ if (!registered) {
664
+ throw new Error(`Resource not registered: ${resource}`);
665
+ }
666
+ const tokens = opts?.tokens ?? 0;
667
+ const result = await this.rateLimitBackend.acquire(
668
+ resource,
669
+ tokens,
670
+ registered.rateLimits
671
+ );
672
+ if (!result.allowed) {
673
+ return { ...result, release: noopRelease };
674
+ }
675
+ const currentActive = this.activeProcessing.get(resource) ?? 0;
676
+ this.activeProcessing.set(resource, currentActive + 1);
677
+ let released = false;
678
+ const release = async () => {
679
+ if (released) {
680
+ return;
681
+ }
682
+ released = true;
683
+ await this.rateLimitBackend.release(resource);
684
+ const active = this.activeProcessing.get(resource) ?? 1;
685
+ this.activeProcessing.set(resource, Math.max(0, active - 1));
686
+ };
687
+ return { ...result, release };
688
+ }
599
689
  /**
600
690
  * Process queue items continuously.
601
691
  */
@@ -1015,6 +1105,7 @@ var StateBrokerRateLimitBackend = class {
1015
1105
  /**
1016
1106
  * @inheritdoc
1017
1107
  */
1108
+ // eslint-disable-next-line sonarjs/cognitive-complexity
1018
1109
  async acquire(resource, tokens, config) {
1019
1110
  const safetyMargin = config.safetyMargin ?? 0.9;
1020
1111
  const [minuteState, secondState, activeCount] = await Promise.all([
@@ -1307,11 +1398,11 @@ var QueuedVectorStore = class {
1307
1398
  * @returns Search results
1308
1399
  * @throws Error if request fails after all retries
1309
1400
  */
1310
- async search(query, limit, filter) {
1401
+ async search(query, limit, filter, namespace) {
1311
1402
  const response = await this.broker.enqueue({
1312
1403
  resource: "vectorStore",
1313
1404
  operation: "search",
1314
- args: [query, limit, filter],
1405
+ args: [query, limit, filter, namespace],
1315
1406
  priority: this._priority
1316
1407
  // No token estimation for vector operations
1317
1408
  });
@@ -1326,11 +1417,11 @@ var QueuedVectorStore = class {
1326
1417
  * @param vectors - Array of vector records to upsert
1327
1418
  * @throws Error if request fails after all retries
1328
1419
  */
1329
- async upsert(vectors) {
1420
+ async upsert(vectors, namespace) {
1330
1421
  const response = await this.broker.enqueue({
1331
1422
  resource: "vectorStore",
1332
1423
  operation: "upsert",
1333
- args: [vectors],
1424
+ args: [vectors, namespace],
1334
1425
  priority: this._priority
1335
1426
  });
1336
1427
  if (!response.success) {
@@ -1343,11 +1434,11 @@ var QueuedVectorStore = class {
1343
1434
  * @param ids - Array of vector IDs to delete
1344
1435
  * @throws Error if request fails after all retries
1345
1436
  */
1346
- async delete(ids) {
1437
+ async delete(ids, namespace) {
1347
1438
  const response = await this.broker.enqueue({
1348
1439
  resource: "vectorStore",
1349
1440
  operation: "delete",
1350
- args: [ids],
1441
+ args: [ids, namespace],
1351
1442
  priority: this._priority
1352
1443
  });
1353
1444
  if (!response.success) {
@@ -1360,11 +1451,11 @@ var QueuedVectorStore = class {
1360
1451
  * @returns Vector count
1361
1452
  * @throws Error if request fails after all retries
1362
1453
  */
1363
- async count() {
1454
+ async count(namespace) {
1364
1455
  const response = await this.broker.enqueue({
1365
1456
  resource: "vectorStore",
1366
1457
  operation: "count",
1367
- args: [],
1458
+ args: [namespace],
1368
1459
  priority: this._priority
1369
1460
  });
1370
1461
  if (!response.success) {
@@ -1379,14 +1470,14 @@ var QueuedVectorStore = class {
1379
1470
  * @returns Array of vector records
1380
1471
  * @throws Error if request fails or method not supported
1381
1472
  */
1382
- async get(ids) {
1473
+ async get(ids, namespace) {
1383
1474
  if (!this.realVectorStore.get) {
1384
1475
  throw new Error("VectorStore.get() not supported by underlying implementation");
1385
1476
  }
1386
1477
  const response = await this.broker.enqueue({
1387
1478
  resource: "vectorStore",
1388
1479
  operation: "get",
1389
- args: [ids],
1480
+ args: [ids, namespace],
1390
1481
  priority: this._priority
1391
1482
  });
1392
1483
  if (!response.success) {
@@ -1401,14 +1492,14 @@ var QueuedVectorStore = class {
1401
1492
  * @returns Array of matching vector records
1402
1493
  * @throws Error if request fails or method not supported
1403
1494
  */
1404
- async query(filter) {
1495
+ async query(filter, namespace) {
1405
1496
  if (!this.realVectorStore.query) {
1406
1497
  throw new Error("VectorStore.query() not supported by underlying implementation");
1407
1498
  }
1408
1499
  const response = await this.broker.enqueue({
1409
1500
  resource: "vectorStore",
1410
1501
  operation: "query",
1411
- args: [filter],
1502
+ args: [filter, namespace],
1412
1503
  priority: this._priority
1413
1504
  });
1414
1505
  if (!response.success) {
@@ -1421,6 +1512,49 @@ function createQueuedVectorStore(broker, vectorStore) {
1421
1512
  return new QueuedVectorStore(broker, vectorStore);
1422
1513
  }
1423
1514
 
1424
- export { DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RETRY_CONFIG, InMemoryRateLimitBackend, PriorityQueue, QueuedEmbeddings, QueuedLLM, QueuedVectorStore, RATE_LIMIT_PRESETS, ResourceBroker, StateBrokerRateLimitBackend, calculateBackoffDelay, classifyError, createQueuedEmbeddings, createQueuedLLM, createQueuedVectorStore, createQuickRetryConfig, createRateLimitRetryConfig, estimateBatchTokens, estimateTokens, extractRetryAfter, getRateLimitConfig, isRateLimitError, isRetryableError, shouldRetry, sleep, withRetry };
1515
+ // src/wrappers/queued-notifier-channel.ts
1516
+ function severityToPriority(severity) {
1517
+ if (severity === "critical") {
1518
+ return "high";
1519
+ }
1520
+ if (severity === "warn") {
1521
+ return "normal";
1522
+ }
1523
+ return "low";
1524
+ }
1525
+ var QueuedNotifierChannel = class {
1526
+ constructor(broker, channel) {
1527
+ this.broker = broker;
1528
+ this.channel = channel;
1529
+ }
1530
+ broker;
1531
+ channel;
1532
+ get id() {
1533
+ return this.channel.id;
1534
+ }
1535
+ get capabilities() {
1536
+ return this.channel.capabilities;
1537
+ }
1538
+ isAvailable() {
1539
+ return this.channel.isAvailable();
1540
+ }
1541
+ async send(event) {
1542
+ const response = await this.broker.enqueue({
1543
+ resource: `notifier:${this.channel.id}`,
1544
+ operation: "send",
1545
+ args: [event],
1546
+ priority: severityToPriority(event.severity),
1547
+ estimatedTokens: 1
1548
+ });
1549
+ if (!response.success) {
1550
+ throw response.error ?? new Error(`Notifier channel '${this.channel.id}' send failed`);
1551
+ }
1552
+ }
1553
+ };
1554
+ function createQueuedNotifierChannel(broker, channel) {
1555
+ return new QueuedNotifierChannel(broker, channel);
1556
+ }
1557
+
1558
+ export { DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RETRY_CONFIG, InMemoryRateLimitBackend, PriorityQueue, QueuedEmbeddings, QueuedLLM, QueuedNotifierChannel, QueuedVectorStore, RATE_LIMIT_PRESETS, ResourceBroker, StateBrokerRateLimitBackend, calculateBackoffDelay, classifyError, createQueuedEmbeddings, createQueuedLLM, createQueuedNotifierChannel, createQueuedVectorStore, createQuickRetryConfig, createRateLimitRetryConfig, estimateBatchTokens, estimateTokens, extractRetryAfter, getRateLimitConfig, isRateLimitError, isRetryableError, shouldRetry, sleep, withRetry };
1425
1559
  //# sourceMappingURL=index.js.map
1426
1560
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/queue/priority-queue.ts","../src/rate-limit/presets.ts","../src/retry/error-classifier.ts","../src/retry/retry-strategy.ts","../src/broker/resource-broker.ts","../src/rate-limit/in-memory-backend.ts","../src/rate-limit/state-broker-backend.ts","../src/wrappers/queued-llm.ts","../src/wrappers/queued-embeddings.ts","../src/wrappers/queued-vector-store.ts"],"names":["endTime","processingTime","safetyMargin","effectiveTPM","effectiveRPM","stats"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/core-resource-broker/types\n * Type definitions for the Resource Broker system.\n *\n * The Resource Broker provides centralized queue management, rate limiting,\n * and retry logic for heavy platform resources (LLM, Embeddings, VectorStore).\n */\n\n// ═══════════════════════════════════════════════════════════════════════════\n// RATE LIMITING\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Rate limiting configuration for a resource.\n * Supports multiple rate limiting strategies (TPM, RPM, RPS, concurrent).\n */\nexport interface RateLimitConfig {\n /**\n * Tokens per minute limit (e.g., OpenAI TPM)\n * If undefined, no token-based rate limiting is applied\n */\n tokensPerMinute?: number;\n\n /**\n * Requests per minute limit (e.g., OpenAI RPM)\n * If undefined, no request-per-minute rate limiting is applied\n */\n requestsPerMinute?: number;\n\n /**\n * Requests per second limit\n * Some APIs (like Sber) use RPS instead of RPM\n */\n requestsPerSecond?: number;\n\n /**\n * Maximum tokens per single request\n * Provider-specific limit\n */\n maxTokensPerRequest?: number;\n\n /**\n * Maximum concurrent requests\n * For local models - GPU/CPU concurrency limit\n */\n maxConcurrentRequests?: number;\n\n /**\n * Safety margin (0-1, default 0.9)\n * Use only X% of the limit to avoid hitting exact boundaries\n */\n safetyMargin?: number;\n}\n\n/**\n * Result of attempting to acquire rate limit capacity.\n */\nexport interface AcquireResult {\n /** Whether the request is allowed to proceed */\n allowed: boolean;\n\n /** Milliseconds to wait if not allowed */\n waitTimeMs?: number;\n\n /** Remaining tokens in current window */\n tokensRemaining?: number;\n\n /** Remaining requests in current window */\n requestsRemaining?: number;\n\n /** Current active concurrent requests */\n activeRequests?: number;\n}\n\n/**\n * Statistics for a rate-limited resource.\n */\nexport interface RateLimitStats {\n /** Resource identifier */\n resource: string;\n\n /** Tokens used in current minute window */\n tokensThisMinute: number;\n\n /** Requests made in current minute window */\n requestsThisMinute: number;\n\n /** Requests made in current second window */\n requestsThisSecond: number;\n\n /** Currently active requests */\n activeRequests: number;\n\n /** Total requests made since start */\n totalRequests: number;\n\n /** Total tokens used since start */\n totalTokens: number;\n\n /** Number of times capacity was unavailable */\n waitCount: number;\n\n /** Total time spent waiting (ms) */\n totalWaitTime: number;\n}\n\n/**\n * Backend abstraction for rate limit state storage.\n * Allows swapping between in-memory and distributed storage.\n */\nexport interface RateLimitBackend {\n /**\n * Atomically check limit and reserve capacity.\n *\n * @param resource - Resource identifier (e.g., 'llm', 'embeddings')\n * @param tokens - Estimated tokens for this request\n * @param config - Rate limit configuration\n * @returns Acquire result with allowed/waitTime\n */\n acquire(\n resource: string,\n tokens: number,\n config: RateLimitConfig\n ): Promise<AcquireResult>;\n\n /**\n * Release a concurrent request slot.\n *\n * @param resource - Resource identifier\n */\n release(resource: string): Promise<void>;\n\n /**\n * Get current statistics for a resource.\n *\n * @param resource - Resource identifier\n */\n getStats(resource: string): Promise<RateLimitStats>;\n\n /**\n * Reset statistics for a resource.\n *\n * @param resource - Resource identifier\n */\n reset(resource: string): Promise<void>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// QUEUE\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Priority levels for resource requests.\n * - high: User-facing operations (commit, interactive queries)\n * - normal: Background operations with reasonable latency expectations\n * - low: Analytics, batch processing, non-urgent tasks\n */\nexport type ResourcePriority = 'high' | 'normal' | 'low';\n\n/**\n * Request to execute a resource operation.\n */\nexport interface ResourceRequest {\n /** Unique request identifier */\n id: string;\n\n /** Resource type ('llm', 'embeddings', 'vectorStore') */\n resource: string;\n\n /** Operation name ('complete', 'embed', 'search') */\n operation: string;\n\n /** Arguments to pass to the operation */\n args: unknown[];\n\n /** Request priority */\n priority: ResourcePriority;\n\n /** Estimated tokens for rate limiting (optional) */\n estimatedTokens?: number;\n\n /** Request timeout in ms (optional, default: 60000) */\n timeout?: number;\n\n /** Max retry attempts (optional, default: 3) */\n maxRetries?: number;\n\n /** Timestamp when request was created */\n createdAt: number;\n}\n\n/**\n * Response from a resource operation.\n */\nexport interface ResourceResponse<T = unknown> {\n /** Whether the operation succeeded */\n success: boolean;\n\n /** Result data if successful */\n data?: T;\n\n /** Error if failed */\n error?: Error;\n\n /** Number of retry attempts made */\n retries: number;\n\n /** Time spent waiting in queue (ms) */\n waitTime: number;\n\n /** Time spent executing the operation (ms) */\n processingTime: number;\n\n /** Total time from request to response (ms) */\n totalTime: number;\n}\n\n/**\n * Queue item wrapping a request with execution context.\n */\nexport interface QueueItem {\n /** The resource request */\n request: ResourceRequest;\n\n /** Resolve function to complete the promise */\n resolve: (response: ResourceResponse) => void;\n\n /** Reject function to fail the promise */\n reject: (error: Error) => void;\n\n /** Timestamp when added to queue */\n enqueuedAt: number;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// RESOURCE BROKER\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Configuration for a registered resource.\n */\nexport interface ResourceConfig {\n /** Rate limit configuration or preset name */\n rateLimits?: RateLimitConfig | string;\n\n /** Maximum retry attempts */\n maxRetries?: number;\n\n /** Base delay for exponential backoff (ms) */\n baseDelay?: number;\n\n /** Maximum delay between retries (ms) */\n maxDelay?: number;\n\n /** Request timeout (ms) */\n timeout?: number;\n\n /** The actual executor function */\n executor: ResourceExecutor;\n}\n\n/**\n * Function that executes a resource operation.\n */\nexport type ResourceExecutor = (\n operation: string,\n args: unknown[]\n) => Promise<unknown>;\n\n/**\n * Statistics for the resource broker.\n */\nexport interface ResourceBrokerStats {\n /** Stats per resource */\n resources: Record<string, ResourceStats>;\n\n /** Total requests processed */\n totalRequests: number;\n\n /** Total successful requests */\n totalSuccess: number;\n\n /** Total failed requests */\n totalErrors: number;\n\n /** Current queue size */\n queueSize: number;\n\n /** Uptime in milliseconds */\n uptime: number;\n}\n\n/**\n * Statistics for a single resource.\n */\nexport interface ResourceStats {\n /** Rate limit stats */\n rateLimits: RateLimitStats;\n\n /** Queue size for this resource */\n queueSize: number;\n\n /** Requests by priority */\n queueByPriority: {\n high: number;\n normal: number;\n low: number;\n };\n\n /** Total requests processed */\n totalRequests: number;\n\n /** Total successful requests */\n totalSuccess: number;\n\n /** Total failed requests */\n totalErrors: number;\n\n /** Average wait time (ms) */\n avgWaitTime: number;\n\n /** Average processing time (ms) */\n avgProcessingTime: number;\n}\n\n/**\n * Main resource broker interface.\n * Coordinates queues, rate limiting, and execution for all resources.\n */\nexport interface IResourceBroker {\n /**\n * Register a resource with its configuration.\n *\n * @param resource - Resource identifier\n * @param config - Resource configuration\n */\n register(resource: string, config: ResourceConfig): void;\n\n /**\n * Enqueue a request for execution.\n * Returns a promise that resolves when the request completes.\n *\n * @param request - Resource request (without id and createdAt)\n * @returns Response with result or error\n */\n enqueue<T>(\n request: Omit<ResourceRequest, 'id' | 'createdAt'>\n ): Promise<ResourceResponse<T>>;\n\n /**\n * Get broker statistics.\n */\n getStats(): ResourceBrokerStats;\n\n /**\n * Graceful shutdown - drain queues and stop processing.\n */\n shutdown(): Promise<void>;\n\n /**\n * Check if broker is shutting down.\n */\n isShuttingDown(): boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// RETRY\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Error classification for retry logic.\n */\nexport type ErrorType =\n | 'rate_limit' // 429 - should retry with backoff\n | 'server_error' // 5xx - should retry\n | 'timeout' // Request timeout - may retry\n | 'client_error' // 4xx (except 429) - should not retry\n | 'network' // Network error - may retry\n | 'unknown'; // Unknown - may retry once\n\n/**\n * Configuration for retry strategy.\n */\nexport interface RetryConfig {\n /** Maximum number of retry attempts */\n maxRetries: number;\n\n /** Base delay in ms (default: 1000) */\n baseDelay: number;\n\n /** Maximum delay in ms (default: 30000) */\n maxDelay: number;\n\n /** Jitter factor (0-1, default: 0.1) */\n jitter: number;\n\n /** Which error types to retry */\n retryableErrors: ErrorType[];\n}\n\n/**\n * Default retry configuration.\n */\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 30000,\n jitter: 0.1,\n retryableErrors: ['rate_limit', 'server_error', 'timeout', 'network'],\n};\n\n/**\n * Default rate limit config (no limits).\n */\nexport const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig = {\n safetyMargin: 0.9,\n};\n","/**\n * @module @kb-labs/core-resource-broker/queue/priority-queue\n * Priority queue implementation with three levels: high, normal, low.\n */\n\nimport type { QueueItem } from '../types.js';\n\n/**\n * Priority queue with three priority levels.\n *\n * - High priority items are always dequeued first\n * - Within the same priority, items are dequeued FIFO\n * - Supports peeking without removing\n *\n * @example\n * ```typescript\n * const queue = new PriorityQueue();\n *\n * queue.enqueue(item1); // normal priority\n * queue.enqueue(item2); // high priority\n *\n * const next = queue.dequeue(); // returns item2 (high priority)\n * ```\n */\nexport class PriorityQueue {\n private high: QueueItem[] = [];\n private normal: QueueItem[] = [];\n private low: QueueItem[] = [];\n\n /**\n * Add an item to the queue.\n *\n * @param item - Queue item to add\n */\n enqueue(item: QueueItem): void {\n const priority = item.request.priority;\n\n switch (priority) {\n case 'high':\n this.high.push(item);\n break;\n case 'low':\n this.low.push(item);\n break;\n default:\n this.normal.push(item);\n }\n }\n\n /**\n * Remove and return the highest priority item.\n *\n * @returns The next item or undefined if queue is empty\n */\n dequeue(): QueueItem | undefined {\n if (this.high.length > 0) {\n return this.high.shift();\n }\n if (this.normal.length > 0) {\n return this.normal.shift();\n }\n if (this.low.length > 0) {\n return this.low.shift();\n }\n return undefined;\n }\n\n /**\n * Peek at the highest priority item without removing it.\n *\n * @returns The next item or undefined if queue is empty\n */\n peek(): QueueItem | undefined {\n if (this.high.length > 0) {\n return this.high[0];\n }\n if (this.normal.length > 0) {\n return this.normal[0];\n }\n if (this.low.length > 0) {\n return this.low[0];\n }\n return undefined;\n }\n\n /**\n * Get total queue size.\n */\n size(): number {\n return this.high.length + this.normal.length + this.low.length;\n }\n\n /**\n * Get queue size by priority.\n */\n sizeByPriority(): { high: number; normal: number; low: number } {\n return {\n high: this.high.length,\n normal: this.normal.length,\n low: this.low.length,\n };\n }\n\n /**\n * Check if queue is empty.\n */\n isEmpty(): boolean {\n return this.size() === 0;\n }\n\n /**\n * Clear all items from the queue.\n *\n * @returns All removed items (for cleanup/rejection)\n */\n clear(): QueueItem[] {\n const all = [...this.high, ...this.normal, ...this.low];\n this.high = [];\n this.normal = [];\n this.low = [];\n return all;\n }\n\n /**\n * Remove a specific item by request ID.\n *\n * @param requestId - ID of the request to remove\n * @returns The removed item or undefined if not found\n */\n remove(requestId: string): QueueItem | undefined {\n // Check high priority\n const highIndex = this.high.findIndex(item => item.request.id === requestId);\n if (highIndex !== -1) {\n return this.high.splice(highIndex, 1)[0];\n }\n\n // Check normal priority\n const normalIndex = this.normal.findIndex(item => item.request.id === requestId);\n if (normalIndex !== -1) {\n return this.normal.splice(normalIndex, 1)[0];\n }\n\n // Check low priority\n const lowIndex = this.low.findIndex(item => item.request.id === requestId);\n if (lowIndex !== -1) {\n return this.low.splice(lowIndex, 1)[0];\n }\n\n return undefined;\n }\n\n /**\n * Get all items for a specific resource.\n *\n * @param resource - Resource identifier\n * @returns Items matching the resource\n */\n getByResource(resource: string): QueueItem[] {\n return [\n ...this.high.filter(item => item.request.resource === resource),\n ...this.normal.filter(item => item.request.resource === resource),\n ...this.low.filter(item => item.request.resource === resource),\n ];\n }\n\n /**\n * Get queue size for a specific resource.\n *\n * @param resource - Resource identifier\n */\n sizeByResource(resource: string): number {\n return (\n this.high.filter(item => item.request.resource === resource).length +\n this.normal.filter(item => item.request.resource === resource).length +\n this.low.filter(item => item.request.resource === resource).length\n );\n }\n\n /**\n * Iterate over all items (for inspection, not removal).\n */\n *[Symbol.iterator](): Iterator<QueueItem> {\n yield* this.high;\n yield* this.normal;\n yield* this.low;\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/rate-limit/presets\n * Pre-configured rate limits for common providers.\n */\n\nimport type { RateLimitConfig } from '../types.js';\n\n/**\n * Pre-configured rate limits for common providers.\n */\nexport const RATE_LIMIT_PRESETS = {\n // ═══════════════════════════════════════════════════════════════════════════\n // OPENAI\n // https://platform.openai.com/docs/guides/rate-limits\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * OpenAI Tier 1 (paid accounts, entry level)\n * Updated Nov 2024: Tier 1 now has 1M TPM for embeddings\n */\n 'openai-tier-1': {\n tokensPerMinute: 1_000_000,\n requestsPerMinute: 3000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.85, // More conservative to avoid edge cases\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 2 (after $50+ spent)\n */\n 'openai-tier-2': {\n tokensPerMinute: 2_000_000,\n requestsPerMinute: 5000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 3\n */\n 'openai-tier-3': {\n tokensPerMinute: 5_000_000,\n requestsPerMinute: 5000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 4\n */\n 'openai-tier-4': {\n tokensPerMinute: 10_000_000,\n requestsPerMinute: 10000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 5 (enterprise)\n */\n 'openai-tier-5': {\n tokensPerMinute: 50_000_000,\n requestsPerMinute: 10000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI GPT-4 specific limits (more restrictive)\n */\n 'openai-gpt4': {\n tokensPerMinute: 150_000,\n requestsPerMinute: 500,\n maxTokensPerRequest: 8192,\n safetyMargin: 0.85,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // ANTHROPIC\n // https://docs.anthropic.com/en/api/rate-limits\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Anthropic Tier 1 (default)\n */\n 'anthropic-tier-1': {\n tokensPerMinute: 40_000,\n requestsPerMinute: 50,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.85,\n } satisfies RateLimitConfig,\n\n /**\n * Anthropic Tier 2\n */\n 'anthropic-tier-2': {\n tokensPerMinute: 80_000,\n requestsPerMinute: 100,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * Anthropic Tier 3\n */\n 'anthropic-tier-3': {\n tokensPerMinute: 160_000,\n requestsPerMinute: 200,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * Anthropic Tier 4\n */\n 'anthropic-tier-4': {\n tokensPerMinute: 400_000,\n requestsPerMinute: 400,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // RUSSIAN PROVIDERS\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Sber GigaChat API\n * Conservative limits for typical access\n */\n 'sber-gigachat': {\n requestsPerMinute: 100,\n requestsPerSecond: 5,\n safetyMargin: 0.8,\n } satisfies RateLimitConfig,\n\n /**\n * Yandex GPT API\n */\n 'yandex-gpt': {\n requestsPerMinute: 100,\n requestsPerSecond: 10,\n safetyMargin: 0.8,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LOCAL MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Local Ollama\n * No external rate limits, only GPU concurrency\n */\n 'ollama-local': {\n maxConcurrentRequests: 4,\n } satisfies RateLimitConfig,\n\n /**\n * Self-hosted vLLM\n */\n 'vllm-local': {\n maxConcurrentRequests: 8,\n requestsPerSecond: 100,\n } satisfies RateLimitConfig,\n\n /**\n * Self-hosted text-embeddings-inference\n */\n 'tei-local': {\n maxConcurrentRequests: 16,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // SPECIAL\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * No rate limiting (for testing or unlimited APIs)\n */\n unlimited: {} satisfies RateLimitConfig,\n\n /**\n * Very conservative (for debugging rate limit issues)\n */\n debug: {\n tokensPerMinute: 10_000,\n requestsPerMinute: 10,\n maxConcurrentRequests: 1,\n safetyMargin: 0.5,\n } satisfies RateLimitConfig,\n} as const;\n\nexport type RateLimitPreset = keyof typeof RATE_LIMIT_PRESETS;\n\n/**\n * Get rate limit config from preset name or custom config.\n *\n * @param configOrPreset - Config object or preset name\n * @returns Resolved rate limit configuration\n *\n * @example\n * ```typescript\n * // Use preset\n * const config = getRateLimitConfig('openai-tier-2');\n *\n * // Use custom config\n * const config = getRateLimitConfig({ tokensPerMinute: 100000 });\n *\n * // Default (openai-tier-2)\n * const config = getRateLimitConfig();\n * ```\n */\nexport function getRateLimitConfig(\n configOrPreset?: RateLimitConfig | RateLimitPreset | string\n): RateLimitConfig {\n if (!configOrPreset) {\n // Default: OpenAI Tier 2 (most common for paid accounts)\n return RATE_LIMIT_PRESETS['openai-tier-2'];\n }\n\n if (typeof configOrPreset === 'string') {\n const preset = RATE_LIMIT_PRESETS[configOrPreset as RateLimitPreset];\n if (!preset) {\n throw new Error(`Unknown rate limit preset: ${configOrPreset}`);\n }\n return preset;\n }\n\n return configOrPreset;\n}\n\n/**\n * Estimate tokens for a text (rough approximation).\n * Uses ~4 characters per token as a conservative estimate.\n *\n * @param text - Text to estimate\n * @returns Estimated token count\n */\nexport function estimateTokens(text: string): number {\n // GPT tokenizers average ~4 chars per token for English\n // Use 3.5 to be more conservative (slightly overestimate)\n return Math.ceil(text.length / 3.5);\n}\n\n/**\n * Estimate tokens for multiple texts.\n *\n * @param texts - Array of texts\n * @returns Total estimated token count\n */\nexport function estimateBatchTokens(texts: string[]): number {\n return texts.reduce((sum, text) => sum + estimateTokens(text), 0);\n}\n","/**\n * @module @kb-labs/core-resource-broker/retry/error-classifier\n * Error classification for retry logic.\n */\n\nimport type { ErrorType } from '../types.js';\n\n/**\n * Classify an error for retry decision.\n *\n * @param error - Error to classify\n * @returns Error type classification\n */\nexport function classifyError(error: unknown): ErrorType {\n if (!error) {\n return 'unknown';\n }\n\n // Handle Error objects\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const name = error.name.toLowerCase();\n\n // Rate limit errors (429)\n if (\n message.includes('429') ||\n message.includes('rate limit') ||\n message.includes('too many requests') ||\n message.includes('quota exceeded') ||\n name.includes('ratelimit')\n ) {\n return 'rate_limit';\n }\n\n // Timeout errors\n if (\n message.includes('timeout') ||\n message.includes('timed out') ||\n message.includes('etimedout') ||\n message.includes('deadline exceeded') ||\n name.includes('timeout')\n ) {\n return 'timeout';\n }\n\n // Network errors\n if (\n message.includes('econnrefused') ||\n message.includes('econnreset') ||\n message.includes('enotfound') ||\n message.includes('network') ||\n message.includes('socket') ||\n message.includes('dns') ||\n name.includes('fetch') ||\n name.includes('network')\n ) {\n return 'network';\n }\n\n // Server errors (5xx)\n if (\n message.includes('500') ||\n message.includes('502') ||\n message.includes('503') ||\n message.includes('504') ||\n message.includes('internal server') ||\n message.includes('bad gateway') ||\n message.includes('service unavailable') ||\n message.includes('gateway timeout')\n ) {\n return 'server_error';\n }\n\n // Client errors (4xx except 429)\n if (\n message.includes('400') ||\n message.includes('401') ||\n message.includes('403') ||\n message.includes('404') ||\n message.includes('bad request') ||\n message.includes('unauthorized') ||\n message.includes('forbidden') ||\n message.includes('not found')\n ) {\n return 'client_error';\n }\n }\n\n // Handle response-like objects with status codes\n if (typeof error === 'object' && error !== null) {\n const obj = error as Record<string, unknown>;\n\n // Check status code\n const status = obj.status ?? obj.statusCode ?? obj.code;\n if (typeof status === 'number') {\n if (status === 429) {return 'rate_limit';}\n if (status >= 500) {return 'server_error';}\n if (status >= 400) {return 'client_error';}\n }\n\n // Check error code string\n const code = obj.code;\n if (typeof code === 'string') {\n const lowerCode = code.toLowerCase();\n if (lowerCode.includes('timeout')) {return 'timeout';}\n if (lowerCode.includes('econnrefused')) {return 'network';}\n if (lowerCode.includes('econnreset')) {return 'network';}\n if (lowerCode.includes('enotfound')) {return 'network';}\n }\n }\n\n return 'unknown';\n}\n\n/**\n * Check if an error is a rate limit error (429).\n */\nexport function isRateLimitError(error: unknown): boolean {\n return classifyError(error) === 'rate_limit';\n}\n\n/**\n * Check if an error is retryable.\n *\n * @param error - Error to check\n * @param retryableTypes - Types that should be retried\n */\nexport function isRetryableError(\n error: unknown,\n retryableTypes: ErrorType[] = ['rate_limit', 'server_error', 'timeout', 'network']\n): boolean {\n const errorType = classifyError(error);\n return retryableTypes.includes(errorType);\n}\n\n/**\n * Extract retry-after hint from error if available.\n *\n * @param error - Error to extract hint from\n * @returns Milliseconds to wait, or undefined\n */\nexport function extractRetryAfter(error: unknown): number | undefined {\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const obj = error as Record<string, unknown>;\n\n // Check common retry-after locations\n const retryAfter =\n obj.retryAfter ??\n obj['retry-after'] ??\n obj.retryAfterMs ??\n (obj.headers as Record<string, unknown> | undefined)?.['retry-after'];\n\n if (typeof retryAfter === 'number') {\n // If less than 1000, assume it's seconds\n return retryAfter < 1000 ? retryAfter * 1000 : retryAfter;\n }\n\n if (typeof retryAfter === 'string') {\n const parsed = parseInt(retryAfter, 10);\n if (!isNaN(parsed)) {\n // If less than 1000, assume it's seconds\n return parsed < 1000 ? parsed * 1000 : parsed;\n }\n }\n\n return undefined;\n}\n","/**\n * @module @kb-labs/core-resource-broker/retry/retry-strategy\n * Exponential backoff retry strategy with jitter.\n */\n\nimport type { RetryConfig, ErrorType } from '../types.js';\nimport { DEFAULT_RETRY_CONFIG } from '../types.js';\nimport { classifyError, extractRetryAfter, isRetryableError } from './error-classifier.js';\n\n/**\n * Result of a retry decision.\n */\nexport interface RetryDecision {\n /** Whether to retry */\n shouldRetry: boolean;\n\n /** Delay before retry (ms) */\n delayMs: number;\n\n /** Error classification */\n errorType: ErrorType;\n\n /** Current attempt number (0-indexed) */\n attempt: number;\n\n /** Maximum attempts allowed */\n maxAttempts: number;\n}\n\n/**\n * Calculate delay with exponential backoff and jitter.\n *\n * Formula: min(maxDelay, baseDelay * 2^attempt) * (1 + random * jitter)\n *\n * @param attempt - Current attempt (0-indexed)\n * @param config - Retry configuration\n * @param retryAfterHint - Optional retry-after hint from error (ms)\n * @returns Delay in milliseconds\n */\nexport function calculateBackoffDelay(\n attempt: number,\n config: RetryConfig,\n retryAfterHint?: number\n): number {\n // If we have a retry-after hint, use it (but cap at maxDelay)\n if (retryAfterHint !== undefined && retryAfterHint > 0) {\n return Math.min(retryAfterHint, config.maxDelay);\n }\n\n // Exponential backoff: baseDelay * 2^attempt\n const exponentialDelay = config.baseDelay * Math.pow(2, attempt);\n\n // Cap at maxDelay\n const cappedDelay = Math.min(exponentialDelay, config.maxDelay);\n\n // Add jitter: delay * (1 + random * jitter)\n const jitterMultiplier = 1 + Math.random() * config.jitter;\n\n return Math.floor(cappedDelay * jitterMultiplier);\n}\n\n/**\n * Decide whether to retry based on error and attempt count.\n *\n * @param error - The error that occurred\n * @param attempt - Current attempt (0-indexed)\n * @param config - Retry configuration\n * @returns Retry decision with delay\n *\n * @example\n * ```typescript\n * const decision = shouldRetry(error, 0, config);\n *\n * if (decision.shouldRetry) {\n * await sleep(decision.delayMs);\n * // retry...\n * } else {\n * throw error;\n * }\n * ```\n */\nexport function shouldRetry(\n error: unknown,\n attempt: number,\n config: Partial<RetryConfig> = {}\n): RetryDecision {\n const fullConfig: RetryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n const errorType = classifyError(error);\n const isRetryable = isRetryableError(error, fullConfig.retryableErrors);\n const hasAttemptsLeft = attempt < fullConfig.maxRetries;\n\n const shouldRetryNow = isRetryable && hasAttemptsLeft;\n\n // Calculate delay only if we're going to retry\n let delayMs = 0;\n if (shouldRetryNow) {\n const retryAfterHint = extractRetryAfter(error);\n\n // For rate limit errors, use longer base delay\n if (errorType === 'rate_limit') {\n const rateLimitConfig: RetryConfig = {\n ...fullConfig,\n baseDelay: Math.max(fullConfig.baseDelay, 5000), // At least 5s for rate limits\n };\n delayMs = calculateBackoffDelay(attempt, rateLimitConfig, retryAfterHint);\n } else {\n delayMs = calculateBackoffDelay(attempt, fullConfig, retryAfterHint);\n }\n }\n\n return {\n shouldRetry: shouldRetryNow,\n delayMs,\n errorType,\n attempt,\n maxAttempts: fullConfig.maxRetries,\n };\n}\n\n/**\n * Execute a function with retry logic.\n *\n * @param fn - Function to execute\n * @param config - Retry configuration\n * @returns Result of the function\n * @throws Last error if all retries exhausted\n *\n * @example\n * ```typescript\n * const result = await withRetry(\n * async () => {\n * return await llm.complete(prompt);\n * },\n * { maxRetries: 3, baseDelay: 1000 }\n * );\n * ```\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config: Partial<RetryConfig> = {}\n): Promise<{ result: T; attempts: number }> {\n const fullConfig: RetryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n let lastError: unknown;\n let attempts = 0;\n\n for (let attempt = 0; attempt <= fullConfig.maxRetries; attempt++) {\n attempts = attempt + 1;\n\n try {\n const result = await fn();\n return { result, attempts };\n } catch (error) {\n lastError = error;\n\n const decision = shouldRetry(error, attempt, fullConfig);\n\n if (!decision.shouldRetry) {\n break;\n }\n\n // Wait before retry\n await sleep(decision.delayMs);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Sleep for a specified duration.\n *\n * @param ms - Milliseconds to sleep\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\n/**\n * Create a retry configuration for rate-limited APIs.\n *\n * @param maxRetries - Maximum retry attempts (default: 5)\n * @returns Retry config optimized for rate limits\n */\nexport function createRateLimitRetryConfig(maxRetries = 5): RetryConfig {\n return {\n maxRetries,\n baseDelay: 5000, // Start with 5s for rate limits\n maxDelay: 60000, // Cap at 1 minute\n jitter: 0.2, // 20% jitter for distributed systems\n retryableErrors: ['rate_limit', 'server_error', 'timeout', 'network'],\n };\n}\n\n/**\n * Create a retry configuration for quick operations.\n *\n * @param maxRetries - Maximum retry attempts (default: 3)\n * @returns Retry config with fast retries\n */\nexport function createQuickRetryConfig(maxRetries = 3): RetryConfig {\n return {\n maxRetries,\n baseDelay: 500, // Start with 500ms\n maxDelay: 5000, // Cap at 5s\n jitter: 0.1, // 10% jitter\n retryableErrors: ['server_error', 'timeout', 'network'],\n };\n}\n","/**\n * @module @kb-labs/core-resource-broker/broker/resource-broker\n * Main ResourceBroker implementation - coordinates queues, rate limiting, and execution.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type {\n IResourceBroker,\n ResourceConfig,\n ResourceRequest,\n ResourceResponse,\n ResourceBrokerStats,\n ResourceStats,\n RateLimitBackend,\n RateLimitConfig,\n QueueItem,\n} from '../types.js';\nimport { DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RETRY_CONFIG } from '../types.js';\nimport { PriorityQueue } from '../queue/priority-queue.js';\nimport { getRateLimitConfig } from '../rate-limit/presets.js';\nimport { shouldRetry, sleep } from '../retry/retry-strategy.js';\n\n/**\n * Internal resource registration with resolved config.\n */\ninterface RegisteredResource {\n config: ResourceConfig;\n rateLimits: RateLimitConfig;\n stats: {\n totalRequests: number;\n totalSuccess: number;\n totalErrors: number;\n totalWaitTime: number;\n totalProcessingTime: number;\n };\n}\n\n/**\n * ResourceBroker - Centralized coordinator for heavy platform resources.\n *\n * Features:\n * - Priority queue (high/normal/low)\n * - Rate limiting with configurable backend (in-memory or distributed)\n * - Automatic retry with exponential backoff\n * - Graceful shutdown\n * - Per-resource statistics\n *\n * The platform doesn't know about plugins - only manages resources.\n * Any caller can enqueue requests with appropriate priority.\n *\n * @example\n * ```typescript\n * const backend = new InMemoryRateLimitBackend();\n * const broker = new ResourceBroker(backend);\n *\n * // Register resources\n * broker.register('llm', {\n * rateLimits: 'openai-tier-2',\n * executor: (op, args) => llmAdapter[op](...args),\n * });\n *\n * // Enqueue request\n * const response = await broker.enqueue({\n * resource: 'llm',\n * operation: 'complete',\n * args: [prompt, options],\n * priority: 'high',\n * estimatedTokens: 1000,\n * });\n * ```\n */\nexport class ResourceBroker implements IResourceBroker {\n private resources = new Map<string, RegisteredResource>();\n private queue = new PriorityQueue();\n private processing = false;\n private shuttingDown = false;\n private startTime = Date.now();\n\n /**\n * Active processing count per resource (for concurrent limit tracking).\n */\n private activeProcessing = new Map<string, number>();\n\n constructor(private rateLimitBackend: RateLimitBackend) {}\n\n /**\n * Register a resource with its configuration.\n *\n * @param resource - Resource identifier ('llm', 'embeddings', 'vectorStore')\n * @param config - Resource configuration including executor\n */\n register(resource: string, config: ResourceConfig): void {\n // Resolve rate limits (preset name or config object)\n const rateLimits =\n typeof config.rateLimits === 'string'\n ? getRateLimitConfig(config.rateLimits)\n : config.rateLimits ?? DEFAULT_RATE_LIMIT_CONFIG;\n\n this.resources.set(resource, {\n config,\n rateLimits,\n stats: {\n totalRequests: 0,\n totalSuccess: 0,\n totalErrors: 0,\n totalWaitTime: 0,\n totalProcessingTime: 0,\n },\n });\n\n this.activeProcessing.set(resource, 0);\n }\n\n /**\n * Enqueue a request for execution.\n *\n * @param request - Resource request (without id and createdAt)\n * @returns Promise that resolves with response when execution completes\n */\n enqueue<T>(\n request: Omit<ResourceRequest, 'id' | 'createdAt'>\n ): Promise<ResourceResponse<T>> {\n if (this.shuttingDown) {\n return Promise.resolve({\n success: false,\n error: new Error('ResourceBroker is shutting down'),\n retries: 0,\n waitTime: 0,\n processingTime: 0,\n totalTime: 0,\n });\n }\n\n const registered = this.resources.get(request.resource);\n if (!registered) {\n return Promise.resolve({\n success: false,\n error: new Error(`Resource not registered: ${request.resource}`),\n retries: 0,\n waitTime: 0,\n processingTime: 0,\n totalTime: 0,\n });\n }\n\n // Create full request\n const fullRequest: ResourceRequest = {\n ...request,\n id: randomUUID(),\n createdAt: Date.now(),\n timeout: request.timeout ?? registered.config.timeout ?? 60000,\n maxRetries: request.maxRetries ?? registered.config.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n\n // Create promise that will be resolved when execution completes\n return new Promise<ResourceResponse<T>>((resolve, reject) => {\n const item: QueueItem = {\n request: fullRequest,\n resolve: resolve as (response: ResourceResponse) => void,\n reject,\n enqueuedAt: Date.now(),\n };\n\n this.queue.enqueue(item);\n registered.stats.totalRequests++;\n\n // Start processing if not already running\n this.processQueue();\n });\n }\n\n /**\n * Process queue items continuously.\n */\n private async processQueue(): Promise<void> {\n // Avoid multiple concurrent processors\n if (this.processing) {\n return;\n }\n\n this.processing = true;\n\n try {\n while (!this.queue.isEmpty() && !this.shuttingDown) {\n const item = this.queue.peek();\n if (!item) {break;}\n\n const registered = this.resources.get(item.request.resource);\n if (!registered) {\n // Resource was unregistered - reject and move on\n this.queue.dequeue();\n item.reject(new Error(`Resource not registered: ${item.request.resource}`));\n continue;\n }\n\n // Check rate limits\n const tokens = item.request.estimatedTokens ?? 0;\n const acquireResult = await this.rateLimitBackend.acquire(\n item.request.resource,\n tokens,\n registered.rateLimits\n );\n\n if (!acquireResult.allowed) {\n // Wait and try again\n await sleep(acquireResult.waitTimeMs ?? 100);\n continue;\n }\n\n // Dequeue and process\n this.queue.dequeue();\n\n // Track active processing\n const currentActive = this.activeProcessing.get(item.request.resource) ?? 0;\n this.activeProcessing.set(item.request.resource, currentActive + 1);\n\n // Process in background (don't block queue processing)\n this.executeItem(item, registered).catch(() => {\n // Errors are handled in executeItem\n });\n }\n } finally {\n this.processing = false;\n\n // Check if there are more items (could have been added during processing)\n if (!this.queue.isEmpty() && !this.shuttingDown) {\n // Schedule next processing cycle\n setImmediate(() => this.processQueue());\n }\n }\n }\n\n /**\n * Execute a single queue item with retry logic.\n */\n private async executeItem(\n item: QueueItem,\n registered: RegisteredResource\n ): Promise<void> {\n const startTime = Date.now();\n const waitTime = startTime - item.enqueuedAt;\n\n let retries = 0;\n let lastError: Error | undefined;\n\n const retryConfig = {\n maxRetries: item.request.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n baseDelay: registered.config.baseDelay ?? DEFAULT_RETRY_CONFIG.baseDelay,\n maxDelay: registered.config.maxDelay ?? DEFAULT_RETRY_CONFIG.maxDelay,\n jitter: DEFAULT_RETRY_CONFIG.jitter,\n retryableErrors: DEFAULT_RETRY_CONFIG.retryableErrors,\n };\n\n try {\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n // Create timeout promise\n const timeoutMs = item.request.timeout ?? 60000;\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Request timeout after ${timeoutMs}ms`)), timeoutMs);\n });\n\n // Execute operation\n const executionPromise = registered.config.executor(\n item.request.operation,\n item.request.args\n );\n\n const result = await Promise.race([executionPromise, timeoutPromise]);\n\n // Success\n const endTime = Date.now();\n const processingTime = endTime - startTime;\n\n registered.stats.totalSuccess++;\n registered.stats.totalWaitTime += waitTime;\n registered.stats.totalProcessingTime += processingTime;\n\n item.resolve({\n success: true,\n data: result,\n retries,\n waitTime,\n processingTime,\n totalTime: endTime - item.enqueuedAt,\n });\n\n return;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n retries = attempt;\n\n const decision = shouldRetry(error, attempt, retryConfig);\n\n if (!decision.shouldRetry) {\n break;\n }\n\n // Wait before retry\n await sleep(decision.delayMs);\n\n // Re-acquire rate limit capacity for retry\n const tokens = item.request.estimatedTokens ?? 0;\n const acquireResult = await this.rateLimitBackend.acquire(\n item.request.resource,\n tokens,\n registered.rateLimits\n );\n\n if (!acquireResult.allowed && acquireResult.waitTimeMs) {\n await sleep(acquireResult.waitTimeMs);\n }\n }\n }\n\n // All retries exhausted\n const endTime = Date.now();\n const processingTime = endTime - startTime;\n\n registered.stats.totalErrors++;\n registered.stats.totalWaitTime += waitTime;\n registered.stats.totalProcessingTime += processingTime;\n\n item.resolve({\n success: false,\n error: lastError,\n retries,\n waitTime,\n processingTime,\n totalTime: endTime - item.enqueuedAt,\n });\n } finally {\n // Release rate limit slot\n await this.rateLimitBackend.release(item.request.resource);\n\n // Update active processing count\n const currentActive = this.activeProcessing.get(item.request.resource) ?? 1;\n this.activeProcessing.set(item.request.resource, Math.max(0, currentActive - 1));\n }\n }\n\n /**\n * Get broker statistics.\n */\n getStats(): ResourceBrokerStats {\n const resources: Record<string, ResourceStats> = {};\n let totalRequests = 0;\n let totalSuccess = 0;\n let totalErrors = 0;\n\n for (const [resourceName, registered] of this.resources) {\n const queueByPriority = this.queue.sizeByPriority();\n const queueSize = this.queue.sizeByResource(resourceName);\n const activeRequests = this.activeProcessing.get(resourceName) ?? 0;\n\n // Get rate limit stats (synchronously create placeholder, async update later)\n const rateLimitStats = {\n resource: resourceName,\n tokensThisMinute: 0,\n requestsThisMinute: 0,\n requestsThisSecond: 0,\n activeRequests,\n totalRequests: registered.stats.totalRequests,\n totalTokens: 0,\n waitCount: 0,\n totalWaitTime: registered.stats.totalWaitTime,\n };\n\n const avgWaitTime =\n registered.stats.totalRequests > 0\n ? registered.stats.totalWaitTime / registered.stats.totalRequests\n : 0;\n\n const avgProcessingTime =\n registered.stats.totalRequests > 0\n ? registered.stats.totalProcessingTime / registered.stats.totalRequests\n : 0;\n\n resources[resourceName] = {\n rateLimits: rateLimitStats,\n queueSize,\n queueByPriority,\n totalRequests: registered.stats.totalRequests,\n totalSuccess: registered.stats.totalSuccess,\n totalErrors: registered.stats.totalErrors,\n avgWaitTime,\n avgProcessingTime,\n };\n\n totalRequests += registered.stats.totalRequests;\n totalSuccess += registered.stats.totalSuccess;\n totalErrors += registered.stats.totalErrors;\n }\n\n return {\n resources,\n totalRequests,\n totalSuccess,\n totalErrors,\n queueSize: this.queue.size(),\n uptime: Date.now() - this.startTime,\n };\n }\n\n /**\n * Graceful shutdown - drain queues and stop processing.\n *\n * @param timeoutMs - Maximum time to wait for drain (default: 30000)\n */\n async shutdown(timeoutMs = 30000): Promise<void> {\n this.shuttingDown = true;\n\n const startTime = Date.now();\n\n // Wait for queue to drain or timeout\n while (!this.queue.isEmpty() && Date.now() - startTime < timeoutMs) {\n await sleep(100);\n }\n\n // Reject remaining items\n const remaining = this.queue.clear();\n for (const item of remaining) {\n item.resolve({\n success: false,\n error: new Error('ResourceBroker shutdown'),\n retries: 0,\n waitTime: Date.now() - item.enqueuedAt,\n processingTime: 0,\n totalTime: Date.now() - item.enqueuedAt,\n });\n }\n }\n\n /**\n * Check if broker is shutting down.\n */\n isShuttingDown(): boolean {\n return this.shuttingDown;\n }\n\n /**\n * Get registered resource names.\n */\n getRegisteredResources(): string[] {\n return Array.from(this.resources.keys());\n }\n\n /**\n * Check if a resource is registered.\n */\n hasResource(resource: string): boolean {\n return this.resources.has(resource);\n }\n\n /**\n * Unregister a resource.\n * Note: Pending requests for this resource will fail.\n */\n unregister(resource: string): void {\n this.resources.delete(resource);\n this.activeProcessing.delete(resource);\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/rate-limit/in-memory-backend\n * In-memory implementation of RateLimitBackend for single-process deployments.\n */\n\nimport type {\n RateLimitBackend,\n RateLimitConfig,\n RateLimitStats,\n AcquireResult,\n} from '../types.js';\n\n/**\n * Internal state for a single resource.\n */\ninterface ResourceState {\n // Window tracking\n tokensThisMinute: number;\n requestsThisMinute: number;\n requestsThisSecond: number;\n activeRequests: number;\n\n // Window timestamps\n minuteWindowStart: number;\n secondWindowStart: number;\n\n // Stats\n totalRequests: number;\n totalTokens: number;\n waitCount: number;\n totalWaitTime: number;\n}\n\n/**\n * In-memory rate limit backend.\n *\n * Uses sliding window approach for TPM/RPM/RPS tracking.\n * Suitable for single-process deployments.\n *\n * @example\n * ```typescript\n * const backend = new InMemoryRateLimitBackend();\n *\n * const result = await backend.acquire('llm', 1000, {\n * tokensPerMinute: 100000,\n * requestsPerMinute: 1000,\n * });\n *\n * if (result.allowed) {\n * // Execute request\n * await backend.release('llm');\n * } else {\n * // Wait and retry\n * await sleep(result.waitTimeMs);\n * }\n * ```\n */\nexport class InMemoryRateLimitBackend implements RateLimitBackend {\n private states = new Map<string, ResourceState>();\n\n /**\n * Get or create state for a resource.\n */\n private getState(resource: string): ResourceState {\n let state = this.states.get(resource);\n if (!state) {\n const now = Date.now();\n state = {\n tokensThisMinute: 0,\n requestsThisMinute: 0,\n requestsThisSecond: 0,\n activeRequests: 0,\n minuteWindowStart: now,\n secondWindowStart: now,\n totalRequests: 0,\n totalTokens: 0,\n waitCount: 0,\n totalWaitTime: 0,\n };\n this.states.set(resource, state);\n }\n return state;\n }\n\n /**\n * Reset windows if time has passed.\n */\n private resetWindowsIfNeeded(state: ResourceState): void {\n const now = Date.now();\n\n // Reset minute window\n if (now - state.minuteWindowStart >= 60_000) {\n state.tokensThisMinute = 0;\n state.requestsThisMinute = 0;\n state.minuteWindowStart = now;\n }\n\n // Reset second window\n if (now - state.secondWindowStart >= 1_000) {\n state.requestsThisSecond = 0;\n state.secondWindowStart = now;\n }\n }\n\n /**\n * Check if all limits allow proceeding.\n */\n private checkLimits(\n state: ResourceState,\n tokens: number,\n config: RateLimitConfig\n ): { allowed: boolean; waitTimeMs?: number } {\n const now = Date.now();\n const safetyMargin = config.safetyMargin ?? 0.9;\n\n // Apply safety margin to limits\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n const effectiveRPS = config.requestsPerSecond\n ? Math.floor(config.requestsPerSecond * safetyMargin)\n : undefined;\n\n const delays: number[] = [];\n\n // Check TPM\n if (effectiveTPM !== undefined && state.tokensThisMinute + tokens > effectiveTPM) {\n const timeUntilMinuteReset = 60_000 - (now - state.minuteWindowStart);\n delays.push(Math.max(100, timeUntilMinuteReset + 100));\n }\n\n // Check RPM\n if (effectiveRPM !== undefined && state.requestsThisMinute >= effectiveRPM) {\n const timeUntilMinuteReset = 60_000 - (now - state.minuteWindowStart);\n delays.push(Math.max(100, timeUntilMinuteReset + 100));\n }\n\n // Check RPS\n if (effectiveRPS !== undefined && state.requestsThisSecond >= effectiveRPS) {\n const timeUntilSecondReset = 1_000 - (now - state.secondWindowStart);\n delays.push(Math.max(50, timeUntilSecondReset + 50));\n }\n\n // Check concurrent requests\n if (\n config.maxConcurrentRequests !== undefined &&\n state.activeRequests >= config.maxConcurrentRequests\n ) {\n delays.push(100); // Check every 100ms for slot availability\n }\n\n if (delays.length > 0) {\n return { allowed: false, waitTimeMs: Math.min(...delays) };\n }\n\n return { allowed: true };\n }\n\n /**\n * @inheritdoc\n */\n async acquire(\n resource: string,\n tokens: number,\n config: RateLimitConfig\n ): Promise<AcquireResult> {\n const state = this.getState(resource);\n this.resetWindowsIfNeeded(state);\n\n const check = this.checkLimits(state, tokens, config);\n\n if (!check.allowed) {\n state.waitCount++;\n state.totalWaitTime += check.waitTimeMs ?? 0;\n\n // Calculate remaining capacity\n const safetyMargin = config.safetyMargin ?? 0.9;\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n\n return {\n allowed: false,\n waitTimeMs: check.waitTimeMs,\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - state.tokensThisMinute)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - state.requestsThisMinute)\n : undefined,\n activeRequests: state.activeRequests,\n };\n }\n\n // Reserve capacity\n state.tokensThisMinute += tokens;\n state.requestsThisMinute++;\n state.requestsThisSecond++;\n state.activeRequests++;\n state.totalRequests++;\n state.totalTokens += tokens;\n\n // Calculate remaining capacity\n const safetyMargin = config.safetyMargin ?? 0.9;\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n\n return {\n allowed: true,\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - state.tokensThisMinute)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - state.requestsThisMinute)\n : undefined,\n activeRequests: state.activeRequests,\n };\n }\n\n /**\n * @inheritdoc\n */\n async release(resource: string): Promise<void> {\n const state = this.states.get(resource);\n if (state) {\n state.activeRequests = Math.max(0, state.activeRequests - 1);\n }\n }\n\n /**\n * @inheritdoc\n */\n async getStats(resource: string): Promise<RateLimitStats> {\n const state = this.getState(resource);\n this.resetWindowsIfNeeded(state);\n\n return {\n resource,\n tokensThisMinute: state.tokensThisMinute,\n requestsThisMinute: state.requestsThisMinute,\n requestsThisSecond: state.requestsThisSecond,\n activeRequests: state.activeRequests,\n totalRequests: state.totalRequests,\n totalTokens: state.totalTokens,\n waitCount: state.waitCount,\n totalWaitTime: state.totalWaitTime,\n };\n }\n\n /**\n * @inheritdoc\n */\n async reset(resource: string): Promise<void> {\n this.states.delete(resource);\n }\n\n /**\n * Reset all resources.\n */\n resetAll(): void {\n this.states.clear();\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/rate-limit/state-broker-backend\n * Distributed rate limit backend using StateBroker.\n *\n * Enables horizontal scaling by storing rate counters in a shared StateBroker\n * (HTTP daemon or future Redis backend).\n */\n\nimport type { StateBroker } from '@kb-labs/core-state-broker';\nimport type {\n RateLimitBackend,\n RateLimitConfig,\n RateLimitStats,\n AcquireResult,\n} from '../types.js';\n\n/**\n * State stored in StateBroker for each resource window.\n */\ninterface WindowState {\n tokens: number;\n requests: number;\n activeRequests: number;\n updatedAt: number;\n}\n\n/**\n * Cumulative stats stored in StateBroker.\n */\ninterface CumulativeStats {\n totalRequests: number;\n totalTokens: number;\n waitCount: number;\n totalWaitTime: number;\n}\n\n/**\n * Distributed rate limit backend using StateBroker.\n *\n * Key patterns:\n * - `ratelimit:{resource}:minute:{YYYY-MM-DDTHH:MM}` - Minute window counters\n * - `ratelimit:{resource}:second:{YYYY-MM-DDTHH:MM:SS}` - Second window counters\n * - `ratelimit:{resource}:active` - Active concurrent requests\n * - `ratelimit:{resource}:stats` - Cumulative statistics\n *\n * TTL strategy:\n * - Minute windows: 120s TTL (allows for clock skew)\n * - Second windows: 10s TTL\n * - Active counter: No TTL (managed explicitly)\n * - Stats: No TTL (persisted)\n *\n * @example\n * ```typescript\n * import { createStateBroker } from '@kb-labs/core-state-broker';\n *\n * const broker = createStateBroker({ backend: 'http', url: 'http://localhost:7777' });\n * const backend = new StateBrokerRateLimitBackend(broker);\n *\n * // Now rate limits are coordinated across all processes using the same daemon\n * ```\n */\nexport class StateBrokerRateLimitBackend implements RateLimitBackend {\n constructor(private broker: StateBroker) {}\n\n /**\n * Get current minute window key.\n */\n private getMinuteKey(resource: string): string {\n const window = new Date().toISOString().slice(0, 16); // YYYY-MM-DDTHH:MM\n return `ratelimit:${resource}:minute:${window}`;\n }\n\n /**\n * Get current second window key.\n */\n private getSecondKey(resource: string): string {\n const window = new Date().toISOString().slice(0, 19); // YYYY-MM-DDTHH:MM:SS\n return `ratelimit:${resource}:second:${window}`;\n }\n\n /**\n * Get active requests key.\n */\n private getActiveKey(resource: string): string {\n return `ratelimit:${resource}:active`;\n }\n\n /**\n * Get stats key.\n */\n private getStatsKey(resource: string): string {\n return `ratelimit:${resource}:stats`;\n }\n\n /**\n * Get or initialize window state.\n */\n private async getWindowState(key: string): Promise<WindowState> {\n const state = await this.broker.get<WindowState>(key);\n return state ?? { tokens: 0, requests: 0, activeRequests: 0, updatedAt: Date.now() };\n }\n\n /**\n * Get or initialize stats.\n */\n private async getCumulativeStats(resource: string): Promise<CumulativeStats> {\n const stats = await this.broker.get<CumulativeStats>(this.getStatsKey(resource));\n return stats ?? { totalRequests: 0, totalTokens: 0, waitCount: 0, totalWaitTime: 0 };\n }\n\n /**\n * @inheritdoc\n */\n async acquire(\n resource: string,\n tokens: number,\n config: RateLimitConfig\n ): Promise<AcquireResult> {\n const safetyMargin = config.safetyMargin ?? 0.9;\n\n // Get current state from all windows\n const [minuteState, secondState, activeCount] = await Promise.all([\n this.getWindowState(this.getMinuteKey(resource)),\n this.getWindowState(this.getSecondKey(resource)),\n this.broker.get<number>(this.getActiveKey(resource)).then(v => v ?? 0),\n ]);\n\n // Calculate effective limits\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n const effectiveRPS = config.requestsPerSecond\n ? Math.floor(config.requestsPerSecond * safetyMargin)\n : undefined;\n\n // Check limits\n const delays: number[] = [];\n const now = Date.now();\n\n // Check TPM\n if (effectiveTPM && minuteState.tokens + tokens > effectiveTPM) {\n // Wait until next minute\n const secondsRemaining = 60 - new Date().getSeconds();\n delays.push(secondsRemaining * 1000 + 100);\n }\n\n // Check RPM\n if (effectiveRPM && minuteState.requests >= effectiveRPM) {\n const secondsRemaining = 60 - new Date().getSeconds();\n delays.push(secondsRemaining * 1000 + 100);\n }\n\n // Check RPS\n if (effectiveRPS && secondState.requests >= effectiveRPS) {\n const msRemaining = 1000 - new Date().getMilliseconds();\n delays.push(msRemaining + 50);\n }\n\n // Check concurrent\n if (config.maxConcurrentRequests && activeCount >= config.maxConcurrentRequests) {\n delays.push(100);\n }\n\n if (delays.length > 0) {\n // Update wait stats\n const stats = await this.getCumulativeStats(resource);\n stats.waitCount++;\n stats.totalWaitTime += Math.min(...delays);\n await this.broker.set(this.getStatsKey(resource), stats);\n\n return {\n allowed: false,\n waitTimeMs: Math.min(...delays),\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - minuteState.tokens)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - minuteState.requests)\n : undefined,\n activeRequests: activeCount,\n };\n }\n\n // Reserve capacity - update all windows atomically as possible\n const minuteKey = this.getMinuteKey(resource);\n const secondKey = this.getSecondKey(resource);\n const activeKey = this.getActiveKey(resource);\n const statsKey = this.getStatsKey(resource);\n\n // Update minute window\n const newMinuteState: WindowState = {\n tokens: minuteState.tokens + tokens,\n requests: minuteState.requests + 1,\n activeRequests: activeCount + 1,\n updatedAt: now,\n };\n await this.broker.set(minuteKey, newMinuteState, 120_000); // 2 min TTL\n\n // Update second window\n const newSecondState: WindowState = {\n tokens: secondState.tokens + tokens,\n requests: secondState.requests + 1,\n activeRequests: activeCount + 1,\n updatedAt: now,\n };\n await this.broker.set(secondKey, newSecondState, 10_000); // 10s TTL\n\n // Update active count\n await this.broker.set(activeKey, activeCount + 1);\n\n // Update cumulative stats\n const stats = await this.getCumulativeStats(resource);\n stats.totalRequests++;\n stats.totalTokens += tokens;\n await this.broker.set(statsKey, stats);\n\n return {\n allowed: true,\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - newMinuteState.tokens)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - newMinuteState.requests)\n : undefined,\n activeRequests: activeCount + 1,\n };\n }\n\n /**\n * @inheritdoc\n */\n async release(resource: string): Promise<void> {\n const activeKey = this.getActiveKey(resource);\n const current = await this.broker.get<number>(activeKey);\n if (current !== null && current > 0) {\n await this.broker.set(activeKey, current - 1);\n }\n }\n\n /**\n * @inheritdoc\n */\n async getStats(resource: string): Promise<RateLimitStats> {\n const [minuteState, secondState, activeCount, cumulativeStats] = await Promise.all([\n this.getWindowState(this.getMinuteKey(resource)),\n this.getWindowState(this.getSecondKey(resource)),\n this.broker.get<number>(this.getActiveKey(resource)).then(v => v ?? 0),\n this.getCumulativeStats(resource),\n ]);\n\n return {\n resource,\n tokensThisMinute: minuteState.tokens,\n requestsThisMinute: minuteState.requests,\n requestsThisSecond: secondState.requests,\n activeRequests: activeCount,\n totalRequests: cumulativeStats.totalRequests,\n totalTokens: cumulativeStats.totalTokens,\n waitCount: cumulativeStats.waitCount,\n totalWaitTime: cumulativeStats.totalWaitTime,\n };\n }\n\n /**\n * @inheritdoc\n */\n async reset(resource: string): Promise<void> {\n // Clear all keys for this resource\n await Promise.all([\n this.broker.clear(`ratelimit:${resource}:*`),\n ]);\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/wrappers/queued-llm\n * QueuedLLM - ILLM wrapper that routes requests through ResourceBroker.\n */\n\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMProtocolCapabilities,\n} from '@kb-labs/core-platform';\nimport type { IResourceBroker, ResourcePriority } from '../types.js';\nimport { estimateTokens } from '../rate-limit/presets.js';\n\n/**\n * Extended LLM options with priority.\n */\nexport interface QueuedLLMOptions extends LLMOptions {\n /** Request priority (default: 'normal') */\n priority?: ResourcePriority;\n}\n\n/**\n * ILLM wrapper that routes requests through ResourceBroker.\n *\n * Features:\n * - Transparent integration (implements ILLM interface)\n * - Automatic token estimation for rate limiting\n * - Priority support for different use cases\n * - Retry and rate limiting handled by broker\n *\n * Note: stream() bypasses the queue for real-time UX.\n *\n * @example\n * ```typescript\n * const queuedLLM = new QueuedLLM(broker, realLLM);\n *\n * // Normal request (goes through queue)\n * const response = await queuedLLM.complete(prompt);\n *\n * // High priority request\n * const response = await queuedLLM.complete(prompt, { priority: 'high' });\n *\n * // Stream (bypasses queue for real-time)\n * for await (const chunk of queuedLLM.stream(prompt)) {\n * process.stdout.write(chunk);\n * }\n * ```\n */\nexport class QueuedLLM implements ILLM {\n constructor(\n private broker: IResourceBroker,\n private realLLM: ILLM\n ) {}\n\n /**\n * Generate a completion through the queue.\n *\n * @param prompt - Text prompt\n * @param options - Optional generation options with priority\n * @returns LLM response\n * @throws Error if request fails after all retries\n */\n async complete(prompt: string, options?: QueuedLLMOptions): Promise<LLMResponse> {\n const priority: ResourcePriority = options?.priority ?? 'normal';\n const estimatedTokens = estimateTokens(prompt);\n\n // Use resource from metadata if provided (set by LLMRouter), fallback to 'llm'\n const resource = options?.metadata?.resource ?? 'llm';\n\n const response = await this.broker.enqueue<LLMResponse>({\n resource,\n operation: 'complete',\n args: [prompt, options],\n priority,\n estimatedTokens,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('LLM request failed');\n }\n\n return response.data!;\n }\n\n async getProtocolCapabilities(): Promise<LLMProtocolCapabilities> {\n if (!this.realLLM.getProtocolCapabilities) {\n return {\n cache: { supported: false },\n stream: { supported: true },\n };\n }\n return this.realLLM.getProtocolCapabilities();\n }\n\n /**\n * Stream a completion (bypasses queue for real-time UX).\n *\n * Streaming is passed through directly to the underlying LLM\n * because:\n * 1. Real-time user experience requires immediate response\n * 2. Token counting happens after streaming completes\n * 3. Rate limits are still enforced by the underlying adapter\n *\n * @param prompt - Text prompt\n * @param options - Optional generation options\n * @returns Async iterable of text chunks\n */\n stream(prompt: string, options?: LLMOptions): AsyncIterable<string> {\n // Pass through to real LLM for real-time streaming\n return this.realLLM.stream(prompt, options);\n }\n\n /**\n * Chat with native tool calling support (proxies to underlying LLM).\n * Currently NOT queued - passes through directly for simplicity.\n * TODO: Add queueing support when needed.\n */\n async chatWithTools(\n messages: LLMMessage[],\n options: LLMToolCallOptions\n ): Promise<LLMToolCallResponse> {\n // Check if underlying LLM supports chatWithTools\n if (!this.realLLM.chatWithTools) {\n throw new Error('Underlying LLM does not support chatWithTools');\n }\n\n // TODO: Route through queue for rate limiting\n // For now, pass through directly to avoid complexity\n return this.realLLM.chatWithTools(messages, options);\n }\n}\n\n/**\n * Create a QueuedLLM wrapper.\n *\n * @param broker - ResourceBroker instance\n * @param llm - Real ILLM implementation\n * @returns Wrapped ILLM that routes through broker\n */\nexport function createQueuedLLM(broker: IResourceBroker, llm: ILLM): QueuedLLM {\n return new QueuedLLM(broker, llm);\n}\n","/**\n * @module @kb-labs/core-resource-broker/wrappers/queued-embeddings\n * QueuedEmbeddings - IEmbeddings wrapper that routes requests through ResourceBroker.\n */\n\nimport type { IEmbeddings } from '@kb-labs/core-platform';\nimport type { IResourceBroker, ResourcePriority } from '../types.js';\nimport { estimateTokens, estimateBatchTokens } from '../rate-limit/presets.js';\n\n/**\n * Options for queued embeddings operations.\n */\nexport interface QueuedEmbeddingsOptions {\n /** Request priority (default: 'normal') */\n priority?: ResourcePriority;\n}\n\n/**\n * IEmbeddings wrapper that routes requests through ResourceBroker.\n *\n * Features:\n * - Transparent integration (implements IEmbeddings interface)\n * - Automatic token estimation for rate limiting\n * - Batch operations with proper token accounting\n * - Priority support for different use cases\n *\n * @example\n * ```typescript\n * const queuedEmbeddings = new QueuedEmbeddings(broker, realEmbeddings);\n *\n * // Single embedding\n * const vector = await queuedEmbeddings.embed(\"Hello world\");\n *\n * // Batch embedding\n * const vectors = await queuedEmbeddings.embedBatch([\"Hello\", \"World\"]);\n * ```\n */\nexport class QueuedEmbeddings implements IEmbeddings {\n private _priority: ResourcePriority = 'normal';\n\n constructor(\n private broker: IResourceBroker,\n private realEmbeddings: IEmbeddings\n ) {}\n\n /**\n * Get embedding dimensions from the underlying implementation.\n */\n get dimensions(): number {\n return this.realEmbeddings.dimensions;\n }\n\n /**\n * Set default priority for subsequent operations.\n *\n * @param priority - Priority level\n * @returns this for chaining\n */\n withPriority(priority: ResourcePriority): this {\n this._priority = priority;\n return this;\n }\n\n /**\n * Generate embedding vector for a single text through the queue.\n *\n * @param text - Input text\n * @returns Embedding vector\n * @throws Error if request fails after all retries\n */\n async embed(text: string): Promise<number[]> {\n const estimatedTokens = estimateTokens(text);\n\n const response = await this.broker.enqueue<number[]>({\n resource: 'embeddings',\n operation: 'embed',\n args: [text],\n priority: this._priority,\n estimatedTokens,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('Embeddings request failed');\n }\n\n return response.data!;\n }\n\n /**\n * Generate embedding vectors for multiple texts through the queue.\n *\n * @param texts - Array of input texts\n * @returns Array of embedding vectors\n * @throws Error if request fails after all retries\n */\n async embedBatch(texts: string[]): Promise<number[][]> {\n const estimatedTokens = estimateBatchTokens(texts);\n\n const response = await this.broker.enqueue<number[][]>({\n resource: 'embeddings',\n operation: 'embedBatch',\n args: [texts],\n priority: this._priority,\n estimatedTokens,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('Embeddings batch request failed');\n }\n\n return response.data!;\n }\n\n /**\n * Get the dimensions of the embeddings.\n * This method is needed for IPC/Unix Socket transport to access the dimensions property.\n */\n async getDimensions(): Promise<number> {\n return this.realEmbeddings.dimensions;\n }\n}\n\n/**\n * Create a QueuedEmbeddings wrapper.\n *\n * @param broker - ResourceBroker instance\n * @param embeddings - Real IEmbeddings implementation\n * @returns Wrapped IEmbeddings that routes through broker\n */\nexport function createQueuedEmbeddings(\n broker: IResourceBroker,\n embeddings: IEmbeddings\n): QueuedEmbeddings {\n return new QueuedEmbeddings(broker, embeddings);\n}\n","/**\n * @module @kb-labs/core-resource-broker/wrappers/queued-vector-store\n * QueuedVectorStore - IVectorStore wrapper that routes requests through ResourceBroker.\n */\n\nimport type {\n IVectorStore,\n VectorRecord,\n VectorSearchResult,\n VectorFilter,\n} from '@kb-labs/core-platform';\nimport type { IResourceBroker, ResourcePriority } from '../types.js';\n\n/**\n * Options for queued vector store operations.\n */\nexport interface QueuedVectorStoreOptions {\n /** Request priority (default: 'normal') */\n priority?: ResourcePriority;\n}\n\n/**\n * IVectorStore wrapper that routes requests through ResourceBroker.\n *\n * Features:\n * - Transparent integration (implements IVectorStore interface)\n * - Rate limiting for batch operations\n * - Priority support for different use cases\n * - Search operations prioritized over bulk upserts\n *\n * @example\n * ```typescript\n * const queuedVectorStore = new QueuedVectorStore(broker, realVectorStore);\n *\n * // Search (typically high priority)\n * const results = await queuedVectorStore.search(queryVector, 10);\n *\n * // Bulk upsert (typically normal/low priority)\n * await queuedVectorStore.upsert(vectors);\n * ```\n */\nexport class QueuedVectorStore implements IVectorStore {\n private _priority: ResourcePriority = 'normal';\n\n constructor(\n private broker: IResourceBroker,\n private realVectorStore: IVectorStore\n ) {}\n\n /**\n * Set default priority for subsequent operations.\n *\n * @param priority - Priority level\n * @returns this for chaining\n */\n withPriority(priority: ResourcePriority): this {\n this._priority = priority;\n return this;\n }\n\n /**\n * Search for similar vectors through the queue.\n *\n * @param query - Query embedding vector\n * @param limit - Maximum number of results\n * @param filter - Optional metadata filter\n * @returns Search results\n * @throws Error if request fails after all retries\n */\n async search(\n query: number[],\n limit: number,\n filter?: VectorFilter\n ): Promise<VectorSearchResult[]> {\n const response = await this.broker.enqueue<VectorSearchResult[]>({\n resource: 'vectorStore',\n operation: 'search',\n args: [query, limit, filter],\n priority: this._priority,\n // No token estimation for vector operations\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore search failed');\n }\n\n return response.data!;\n }\n\n /**\n * Upsert vectors through the queue.\n *\n * @param vectors - Array of vector records to upsert\n * @throws Error if request fails after all retries\n */\n async upsert(vectors: VectorRecord[]): Promise<void> {\n const response = await this.broker.enqueue<void>({\n resource: 'vectorStore',\n operation: 'upsert',\n args: [vectors],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore upsert failed');\n }\n }\n\n /**\n * Delete vectors through the queue.\n *\n * @param ids - Array of vector IDs to delete\n * @throws Error if request fails after all retries\n */\n async delete(ids: string[]): Promise<void> {\n const response = await this.broker.enqueue<void>({\n resource: 'vectorStore',\n operation: 'delete',\n args: [ids],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore delete failed');\n }\n }\n\n /**\n * Get total count of vectors through the queue.\n *\n * @returns Vector count\n * @throws Error if request fails after all retries\n */\n async count(): Promise<number> {\n const response = await this.broker.enqueue<number>({\n resource: 'vectorStore',\n operation: 'count',\n args: [],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore count failed');\n }\n\n return response.data!;\n }\n\n /**\n * Get vectors by IDs through the queue (if supported).\n *\n * @param ids - Array of vector IDs to retrieve\n * @returns Array of vector records\n * @throws Error if request fails or method not supported\n */\n async get(ids: string[]): Promise<VectorRecord[]> {\n if (!this.realVectorStore.get) {\n throw new Error('VectorStore.get() not supported by underlying implementation');\n }\n\n const response = await this.broker.enqueue<VectorRecord[]>({\n resource: 'vectorStore',\n operation: 'get',\n args: [ids],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore get failed');\n }\n\n return response.data!;\n }\n\n /**\n * Query vectors by filter through the queue (if supported).\n *\n * @param filter - Metadata filter to apply\n * @returns Array of matching vector records\n * @throws Error if request fails or method not supported\n */\n async query(filter: VectorFilter): Promise<VectorRecord[]> {\n if (!this.realVectorStore.query) {\n throw new Error('VectorStore.query() not supported by underlying implementation');\n }\n\n const response = await this.broker.enqueue<VectorRecord[]>({\n resource: 'vectorStore',\n operation: 'query',\n args: [filter],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore query failed');\n }\n\n return response.data!;\n }\n}\n\n/**\n * Create a QueuedVectorStore wrapper.\n *\n * @param broker - ResourceBroker instance\n * @param vectorStore - Real IVectorStore implementation\n * @returns Wrapped IVectorStore that routes through broker\n */\nexport function createQueuedVectorStore(\n broker: IResourceBroker,\n vectorStore: IVectorStore\n): QueuedVectorStore {\n return new QueuedVectorStore(broker, vectorStore);\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/queue/priority-queue.ts","../src/rate-limit/presets.ts","../src/retry/error-classifier.ts","../src/retry/retry-strategy.ts","../src/broker/resource-broker.ts","../src/rate-limit/in-memory-backend.ts","../src/rate-limit/state-broker-backend.ts","../src/wrappers/queued-llm.ts","../src/wrappers/queued-embeddings.ts","../src/wrappers/queued-vector-store.ts","../src/wrappers/queued-notifier-channel.ts"],"names":["endTime","processingTime","safetyMargin","effectiveTPM","effectiveRPM","stats"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/core-resource-broker/types\n * Type definitions for the Resource Broker system.\n *\n * The Resource Broker provides centralized queue management, rate limiting,\n * and retry logic for heavy platform resources (LLM, Embeddings, VectorStore).\n */\n\n// ═══════════════════════════════════════════════════════════════════════════\n// RATE LIMITING\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Rate limiting configuration for a resource.\n * Supports multiple rate limiting strategies (TPM, RPM, RPS, concurrent).\n */\nexport interface RateLimitConfig {\n /**\n * Tokens per minute limit (e.g., OpenAI TPM)\n * If undefined, no token-based rate limiting is applied\n */\n tokensPerMinute?: number;\n\n /**\n * Requests per minute limit (e.g., OpenAI RPM)\n * If undefined, no request-per-minute rate limiting is applied\n */\n requestsPerMinute?: number;\n\n /**\n * Requests per second limit\n * Some APIs (like Sber) use RPS instead of RPM\n */\n requestsPerSecond?: number;\n\n /**\n * Maximum tokens per single request\n * Provider-specific limit\n */\n maxTokensPerRequest?: number;\n\n /**\n * Maximum concurrent requests\n * For local models - GPU/CPU concurrency limit\n */\n maxConcurrentRequests?: number;\n\n /**\n * Safety margin (0-1, default 0.9)\n * Use only X% of the limit to avoid hitting exact boundaries\n */\n safetyMargin?: number;\n}\n\n/**\n * Result of attempting to acquire rate limit capacity.\n */\nexport interface AcquireResult {\n /** Whether the request is allowed to proceed */\n allowed: boolean;\n\n /** Milliseconds to wait if not allowed */\n waitTimeMs?: number;\n\n /** Remaining tokens in current window */\n tokensRemaining?: number;\n\n /** Remaining requests in current window */\n requestsRemaining?: number;\n\n /** Current active concurrent requests */\n activeRequests?: number;\n}\n\n/**\n * Statistics for a rate-limited resource.\n */\nexport interface RateLimitStats {\n /** Resource identifier */\n resource: string;\n\n /** Tokens used in current minute window */\n tokensThisMinute: number;\n\n /** Requests made in current minute window */\n requestsThisMinute: number;\n\n /** Requests made in current second window */\n requestsThisSecond: number;\n\n /** Currently active requests */\n activeRequests: number;\n\n /** Total requests made since start */\n totalRequests: number;\n\n /** Total tokens used since start */\n totalTokens: number;\n\n /** Number of times capacity was unavailable */\n waitCount: number;\n\n /** Total time spent waiting (ms) */\n totalWaitTime: number;\n}\n\n/**\n * Backend abstraction for rate limit state storage.\n * Allows swapping between in-memory and distributed storage.\n */\nexport interface RateLimitBackend {\n /**\n * Atomically check limit and reserve capacity.\n *\n * @param resource - Resource identifier (e.g., 'llm', 'embeddings')\n * @param tokens - Estimated tokens for this request\n * @param config - Rate limit configuration\n * @returns Acquire result with allowed/waitTime\n */\n acquire(\n resource: string,\n tokens: number,\n config: RateLimitConfig\n ): Promise<AcquireResult>;\n\n /**\n * Release a concurrent request slot.\n *\n * @param resource - Resource identifier\n */\n release(resource: string): Promise<void>;\n\n /**\n * Get current statistics for a resource.\n *\n * @param resource - Resource identifier\n */\n getStats(resource: string): Promise<RateLimitStats>;\n\n /**\n * Reset statistics for a resource.\n *\n * @param resource - Resource identifier\n */\n reset(resource: string): Promise<void>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// QUEUE\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Priority levels for resource requests.\n * - high: User-facing operations (commit, interactive queries)\n * - normal: Background operations with reasonable latency expectations\n * - low: Analytics, batch processing, non-urgent tasks\n */\nexport type ResourcePriority = 'high' | 'normal' | 'low';\n\n/**\n * Request to execute a resource operation.\n */\nexport interface ResourceRequest {\n /** Unique request identifier */\n id: string;\n\n /** Resource type ('llm', 'embeddings', 'vectorStore') */\n resource: string;\n\n /** Operation name ('complete', 'embed', 'search') */\n operation: string;\n\n /** Arguments to pass to the operation */\n args: unknown[];\n\n /** Request priority */\n priority: ResourcePriority;\n\n /** Estimated tokens for rate limiting (optional) */\n estimatedTokens?: number;\n\n /** Request timeout in ms (optional, default: 60000) */\n timeout?: number;\n\n /** Max retry attempts (optional, default: 3) */\n maxRetries?: number;\n\n /** Timestamp when request was created */\n createdAt: number;\n}\n\n/**\n * Response from a resource operation.\n */\nexport interface ResourceResponse<T = unknown> {\n /** Whether the operation succeeded */\n success: boolean;\n\n /** Result data if successful */\n data?: T;\n\n /** Error if failed */\n error?: Error;\n\n /** Number of retry attempts made */\n retries: number;\n\n /** Time spent waiting in queue (ms) */\n waitTime: number;\n\n /** Time spent executing the operation (ms) */\n processingTime: number;\n\n /** Total time from request to response (ms) */\n totalTime: number;\n}\n\n/**\n * Queue item wrapping a request with execution context.\n */\nexport interface QueueItem {\n /** The resource request */\n request: ResourceRequest;\n\n /** Resolve function to complete the promise */\n resolve: (response: ResourceResponse) => void;\n\n /** Reject function to fail the promise */\n reject: (error: Error) => void;\n\n /** Timestamp when added to queue */\n enqueuedAt: number;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// RESOURCE BROKER\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Configuration for a registered resource.\n */\nexport interface ResourceConfig {\n /** Rate limit configuration or preset name */\n rateLimits?: RateLimitConfig | string;\n\n /** Maximum retry attempts */\n maxRetries?: number;\n\n /** Base delay for exponential backoff (ms) */\n baseDelay?: number;\n\n /** Maximum delay between retries (ms) */\n maxDelay?: number;\n\n /** Request timeout (ms) */\n timeout?: number;\n\n /** The actual executor function */\n executor: ResourceExecutor;\n}\n\n/**\n * Function that executes a resource operation.\n */\nexport type ResourceExecutor = (\n operation: string,\n args: unknown[]\n) => Promise<unknown>;\n\n/**\n * Statistics for the resource broker.\n */\nexport interface ResourceBrokerStats {\n /** Stats per resource */\n resources: Record<string, ResourceStats>;\n\n /** Total requests processed */\n totalRequests: number;\n\n /** Total successful requests */\n totalSuccess: number;\n\n /** Total failed requests */\n totalErrors: number;\n\n /** Current queue size */\n queueSize: number;\n\n /** Uptime in milliseconds */\n uptime: number;\n}\n\n/**\n * Statistics for a single resource.\n */\nexport interface ResourceStats {\n /** Rate limit stats */\n rateLimits: RateLimitStats;\n\n /** Queue size for this resource */\n queueSize: number;\n\n /** Requests by priority */\n queueByPriority: {\n high: number;\n normal: number;\n low: number;\n };\n\n /** Total requests processed */\n totalRequests: number;\n\n /** Total successful requests */\n totalSuccess: number;\n\n /** Total failed requests */\n totalErrors: number;\n\n /** Average wait time (ms) */\n avgWaitTime: number;\n\n /** Average processing time (ms) */\n avgProcessingTime: number;\n}\n\n/**\n * Options for `IResourceBroker.tryAcquire`.\n */\nexport interface TryAcquireOptions {\n /**\n * Estimated tokens for this acquisition.\n * Default: 0 — HTTP endpoints typically don't consume LLM tokens.\n */\n tokens?: number;\n}\n\n/**\n * Result of `IResourceBroker.tryAcquire`. Extends `AcquireResult` with a\n * caller-bound `release` handle.\n *\n * Contract:\n * - When `allowed=true`, the caller MUST invoke `release()` once the work\n * is done (typically in a `finally` block).\n * - `release()` is idempotent: multiple calls are safe.\n * - When `allowed=false`, `release()` is a no-op so callers can use the\n * unconditional `try { ... } finally { result.release() }` pattern.\n */\nexport interface TryAcquireResult extends AcquireResult {\n release: () => Promise<void>;\n}\n\n/**\n * Main resource broker interface.\n * Coordinates queues, rate limiting, and execution for all resources.\n *\n * Supports two patterns:\n * - **queue + execute** — `register` + `enqueue`. For LLM, embeddings, vector\n * store calls where long, asynchronous work is queued and retried.\n * - **check + reject** — `registerLimit` + `tryAcquire`. For HTTP endpoints\n * (webhook routers, public APIs) that need an immediate accept/reject\n * decision without queueing.\n */\nexport interface IResourceBroker {\n /**\n * Register a resource with its configuration.\n *\n * @param resource - Resource identifier\n * @param config - Resource configuration\n */\n register(resource: string, config: ResourceConfig): void;\n\n /**\n * Register a resource for limit-only usage (no executor, no queue).\n *\n * Use together with `tryAcquire` for HTTP-style \"check + reject\" pressure\n * control. Calling `enqueue` against a limit-only resource resolves with\n * `{ success: false, error }` — it does not throw.\n *\n * @param resource - Resource identifier\n * @param rateLimits - Rate limit configuration or preset name\n */\n registerLimit(resource: string, rateLimits: RateLimitConfig | string): void;\n\n /**\n * Enqueue a request for execution.\n * Returns a promise that resolves when the request completes.\n *\n * @param request - Resource request (without id and createdAt)\n * @returns Response with result or error\n */\n enqueue<T>(\n request: Omit<ResourceRequest, 'id' | 'createdAt'>\n ): Promise<ResourceResponse<T>>;\n\n /**\n * Atomically check and reserve rate-limit capacity without queueing.\n * Returns immediately. Intended for HTTP endpoints that must accept or\n * reject inbound requests synchronously.\n *\n * - On `allowed=true`, the caller MUST invoke `result.release()` once the\n * request has been served.\n * - On `allowed=false`, `result.release()` is a no-op.\n * - Throws if the resource has not been registered (programming error).\n * - Returns `{ allowed: false, release: noop }` after `shutdown()`.\n *\n * @param resource - Resource identifier\n * @param opts - Acquisition options (e.g., estimated tokens)\n */\n tryAcquire(\n resource: string,\n opts?: TryAcquireOptions\n ): Promise<TryAcquireResult>;\n\n /**\n * Get broker statistics.\n */\n getStats(): ResourceBrokerStats;\n\n /**\n * Graceful shutdown - drain queues and stop processing.\n */\n shutdown(): Promise<void>;\n\n /**\n * Check if broker is shutting down.\n */\n isShuttingDown(): boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// RETRY\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Error classification for retry logic.\n */\nexport type ErrorType =\n | 'rate_limit' // 429 - should retry with backoff\n | 'server_error' // 5xx - should retry\n | 'timeout' // Request timeout - may retry\n | 'client_error' // 4xx (except 429) - should not retry\n | 'network' // Network error - may retry\n | 'unknown'; // Unknown - may retry once\n\n/**\n * Configuration for retry strategy.\n */\nexport interface RetryConfig {\n /** Maximum number of retry attempts */\n maxRetries: number;\n\n /** Base delay in ms (default: 1000) */\n baseDelay: number;\n\n /** Maximum delay in ms (default: 30000) */\n maxDelay: number;\n\n /** Jitter factor (0-1, default: 0.1) */\n jitter: number;\n\n /** Which error types to retry */\n retryableErrors: ErrorType[];\n}\n\n/**\n * Default retry configuration.\n */\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 30000,\n jitter: 0.1,\n retryableErrors: ['rate_limit', 'server_error', 'timeout', 'network'],\n};\n\n/**\n * Default rate limit config (no limits).\n */\nexport const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig = {\n safetyMargin: 0.9,\n};\n","/**\n * @module @kb-labs/core-resource-broker/queue/priority-queue\n * Priority queue implementation with three levels: high, normal, low.\n */\n\nimport type { QueueItem } from '../types.js';\n\n/**\n * Priority queue with three priority levels.\n *\n * - High priority items are always dequeued first\n * - Within the same priority, items are dequeued FIFO\n * - Supports peeking without removing\n *\n * @example\n * ```typescript\n * const queue = new PriorityQueue();\n *\n * queue.enqueue(item1); // normal priority\n * queue.enqueue(item2); // high priority\n *\n * const next = queue.dequeue(); // returns item2 (high priority)\n * ```\n */\nexport class PriorityQueue {\n private high: QueueItem[] = [];\n private normal: QueueItem[] = [];\n private low: QueueItem[] = [];\n\n /**\n * Add an item to the queue.\n *\n * @param item - Queue item to add\n */\n enqueue(item: QueueItem): void {\n const priority = item.request.priority;\n\n switch (priority) {\n case 'high':\n this.high.push(item);\n break;\n case 'low':\n this.low.push(item);\n break;\n default:\n this.normal.push(item);\n }\n }\n\n /**\n * Remove and return the highest priority item.\n *\n * @returns The next item or undefined if queue is empty\n */\n dequeue(): QueueItem | undefined {\n if (this.high.length > 0) {\n return this.high.shift();\n }\n if (this.normal.length > 0) {\n return this.normal.shift();\n }\n if (this.low.length > 0) {\n return this.low.shift();\n }\n return undefined;\n }\n\n /**\n * Peek at the highest priority item without removing it.\n *\n * @returns The next item or undefined if queue is empty\n */\n peek(): QueueItem | undefined {\n if (this.high.length > 0) {\n return this.high[0];\n }\n if (this.normal.length > 0) {\n return this.normal[0];\n }\n if (this.low.length > 0) {\n return this.low[0];\n }\n return undefined;\n }\n\n /**\n * Get total queue size.\n */\n size(): number {\n return this.high.length + this.normal.length + this.low.length;\n }\n\n /**\n * Get queue size by priority.\n */\n sizeByPriority(): { high: number; normal: number; low: number } {\n return {\n high: this.high.length,\n normal: this.normal.length,\n low: this.low.length,\n };\n }\n\n /**\n * Check if queue is empty.\n */\n isEmpty(): boolean {\n return this.size() === 0;\n }\n\n /**\n * Clear all items from the queue.\n *\n * @returns All removed items (for cleanup/rejection)\n */\n clear(): QueueItem[] {\n const all = [...this.high, ...this.normal, ...this.low];\n this.high = [];\n this.normal = [];\n this.low = [];\n return all;\n }\n\n /**\n * Remove a specific item by request ID.\n *\n * @param requestId - ID of the request to remove\n * @returns The removed item or undefined if not found\n */\n remove(requestId: string): QueueItem | undefined {\n // Check high priority\n const highIndex = this.high.findIndex(item => item.request.id === requestId);\n if (highIndex !== -1) {\n return this.high.splice(highIndex, 1)[0];\n }\n\n // Check normal priority\n const normalIndex = this.normal.findIndex(item => item.request.id === requestId);\n if (normalIndex !== -1) {\n return this.normal.splice(normalIndex, 1)[0];\n }\n\n // Check low priority\n const lowIndex = this.low.findIndex(item => item.request.id === requestId);\n if (lowIndex !== -1) {\n return this.low.splice(lowIndex, 1)[0];\n }\n\n return undefined;\n }\n\n /**\n * Get all items for a specific resource.\n *\n * @param resource - Resource identifier\n * @returns Items matching the resource\n */\n getByResource(resource: string): QueueItem[] {\n return [\n ...this.high.filter(item => item.request.resource === resource),\n ...this.normal.filter(item => item.request.resource === resource),\n ...this.low.filter(item => item.request.resource === resource),\n ];\n }\n\n /**\n * Get queue size for a specific resource.\n *\n * @param resource - Resource identifier\n */\n sizeByResource(resource: string): number {\n return (\n this.high.filter(item => item.request.resource === resource).length +\n this.normal.filter(item => item.request.resource === resource).length +\n this.low.filter(item => item.request.resource === resource).length\n );\n }\n\n /**\n * Iterate over all items (for inspection, not removal).\n */\n *[Symbol.iterator](): Iterator<QueueItem> {\n yield* this.high;\n yield* this.normal;\n yield* this.low;\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/rate-limit/presets\n * Pre-configured rate limits for common providers.\n */\n\nimport type { RateLimitConfig } from '../types.js';\n\n/**\n * Pre-configured rate limits for common providers.\n */\nexport const RATE_LIMIT_PRESETS = {\n // ═══════════════════════════════════════════════════════════════════════════\n // OPENAI\n // https://platform.openai.com/docs/guides/rate-limits\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * OpenAI Tier 1 (paid accounts, entry level)\n * Updated Nov 2024: Tier 1 now has 1M TPM for embeddings\n */\n 'openai-tier-1': {\n tokensPerMinute: 1_000_000,\n requestsPerMinute: 3000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.85, // More conservative to avoid edge cases\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 2 (after $50+ spent)\n */\n 'openai-tier-2': {\n tokensPerMinute: 2_000_000,\n requestsPerMinute: 5000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 3\n */\n 'openai-tier-3': {\n tokensPerMinute: 5_000_000,\n requestsPerMinute: 5000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 4\n */\n 'openai-tier-4': {\n tokensPerMinute: 10_000_000,\n requestsPerMinute: 10000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI Tier 5 (enterprise)\n */\n 'openai-tier-5': {\n tokensPerMinute: 50_000_000,\n requestsPerMinute: 10000,\n maxTokensPerRequest: 8191,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * OpenAI GPT-4 specific limits (more restrictive)\n */\n 'openai-gpt4': {\n tokensPerMinute: 150_000,\n requestsPerMinute: 500,\n maxTokensPerRequest: 8192,\n safetyMargin: 0.85,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // ANTHROPIC\n // https://docs.anthropic.com/en/api/rate-limits\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Anthropic Tier 1 (default)\n */\n 'anthropic-tier-1': {\n tokensPerMinute: 40_000,\n requestsPerMinute: 50,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.85,\n } satisfies RateLimitConfig,\n\n /**\n * Anthropic Tier 2\n */\n 'anthropic-tier-2': {\n tokensPerMinute: 80_000,\n requestsPerMinute: 100,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * Anthropic Tier 3\n */\n 'anthropic-tier-3': {\n tokensPerMinute: 160_000,\n requestsPerMinute: 200,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n /**\n * Anthropic Tier 4\n */\n 'anthropic-tier-4': {\n tokensPerMinute: 400_000,\n requestsPerMinute: 400,\n maxTokensPerRequest: 4096,\n safetyMargin: 0.9,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // RUSSIAN PROVIDERS\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Sber GigaChat API\n * Conservative limits for typical access\n */\n 'sber-gigachat': {\n requestsPerMinute: 100,\n requestsPerSecond: 5,\n safetyMargin: 0.8,\n } satisfies RateLimitConfig,\n\n /**\n * Yandex GPT API\n */\n 'yandex-gpt': {\n requestsPerMinute: 100,\n requestsPerSecond: 10,\n safetyMargin: 0.8,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // LOCAL MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Local Ollama\n * No external rate limits, only GPU concurrency\n */\n 'ollama-local': {\n maxConcurrentRequests: 4,\n } satisfies RateLimitConfig,\n\n /**\n * Self-hosted vLLM\n */\n 'vllm-local': {\n maxConcurrentRequests: 8,\n requestsPerSecond: 100,\n } satisfies RateLimitConfig,\n\n /**\n * Self-hosted text-embeddings-inference\n */\n 'tei-local': {\n maxConcurrentRequests: 16,\n } satisfies RateLimitConfig,\n\n // ═══════════════════════════════════════════════════════════════════════════\n // SPECIAL\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * No rate limiting (for testing or unlimited APIs)\n */\n unlimited: {} satisfies RateLimitConfig,\n\n /**\n * Very conservative (for debugging rate limit issues)\n */\n debug: {\n tokensPerMinute: 10_000,\n requestsPerMinute: 10,\n maxConcurrentRequests: 1,\n safetyMargin: 0.5,\n } satisfies RateLimitConfig,\n} as const;\n\nexport type RateLimitPreset = keyof typeof RATE_LIMIT_PRESETS;\n\n/**\n * Get rate limit config from preset name or custom config.\n *\n * @param configOrPreset - Config object or preset name\n * @returns Resolved rate limit configuration\n *\n * @example\n * ```typescript\n * // Use preset\n * const config = getRateLimitConfig('openai-tier-2');\n *\n * // Use custom config\n * const config = getRateLimitConfig({ tokensPerMinute: 100000 });\n *\n * // Default (openai-tier-2)\n * const config = getRateLimitConfig();\n * ```\n */\nexport function getRateLimitConfig(\n configOrPreset?: RateLimitConfig | RateLimitPreset | string\n): RateLimitConfig {\n if (!configOrPreset) {\n // Default: OpenAI Tier 2 (most common for paid accounts)\n return RATE_LIMIT_PRESETS['openai-tier-2'];\n }\n\n if (typeof configOrPreset === 'string') {\n const preset = RATE_LIMIT_PRESETS[configOrPreset as RateLimitPreset];\n if (!preset) {\n throw new Error(`Unknown rate limit preset: ${configOrPreset}`);\n }\n return preset;\n }\n\n return configOrPreset;\n}\n\n/**\n * Estimate tokens for a text (rough approximation).\n * Uses ~4 characters per token as a conservative estimate.\n *\n * @param text - Text to estimate\n * @returns Estimated token count\n */\nexport function estimateTokens(text: string): number {\n // GPT tokenizers average ~4 chars per token for English\n // Use 3.5 to be more conservative (slightly overestimate)\n return Math.ceil(text.length / 3.5);\n}\n\n/**\n * Estimate tokens for multiple texts.\n *\n * @param texts - Array of texts\n * @returns Total estimated token count\n */\nexport function estimateBatchTokens(texts: string[]): number {\n return texts.reduce((sum, text) => sum + estimateTokens(text), 0);\n}\n","/**\n * @module @kb-labs/core-resource-broker/retry/error-classifier\n * Error classification for retry logic.\n */\n\nimport type { ErrorType } from '../types.js';\n\n/**\n * Classify an error for retry decision.\n *\n * @param error - Error to classify\n * @returns Error type classification\n */\nexport function classifyError(error: unknown): ErrorType {\n if (!error) {\n return 'unknown';\n }\n\n // Handle Error objects\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n const name = error.name.toLowerCase();\n\n // Rate limit errors (429)\n if (\n message.includes('429') ||\n message.includes('rate limit') ||\n message.includes('too many requests') ||\n message.includes('quota exceeded') ||\n name.includes('ratelimit')\n ) {\n return 'rate_limit';\n }\n\n // Timeout errors\n if (\n message.includes('timeout') ||\n message.includes('timed out') ||\n message.includes('etimedout') ||\n message.includes('deadline exceeded') ||\n name.includes('timeout')\n ) {\n return 'timeout';\n }\n\n // Network errors\n if (\n message.includes('econnrefused') ||\n message.includes('econnreset') ||\n message.includes('enotfound') ||\n message.includes('network') ||\n message.includes('socket') ||\n message.includes('dns') ||\n name.includes('fetch') ||\n name.includes('network')\n ) {\n return 'network';\n }\n\n // Server errors (5xx)\n if (\n message.includes('500') ||\n message.includes('502') ||\n message.includes('503') ||\n message.includes('504') ||\n message.includes('internal server') ||\n message.includes('bad gateway') ||\n message.includes('service unavailable') ||\n message.includes('gateway timeout')\n ) {\n return 'server_error';\n }\n\n // Client errors (4xx except 429)\n if (\n message.includes('400') ||\n message.includes('401') ||\n message.includes('403') ||\n message.includes('404') ||\n message.includes('bad request') ||\n message.includes('unauthorized') ||\n message.includes('forbidden') ||\n message.includes('not found')\n ) {\n return 'client_error';\n }\n }\n\n // Handle response-like objects with status codes\n if (typeof error === 'object' && error !== null) {\n const obj = error as Record<string, unknown>;\n\n // Check status code\n const status = obj.status ?? obj.statusCode ?? obj.code;\n if (typeof status === 'number') {\n if (status === 429) {return 'rate_limit';}\n if (status >= 500) {return 'server_error';}\n if (status >= 400) {return 'client_error';}\n }\n\n // Check error code string\n const code = obj.code;\n if (typeof code === 'string') {\n const lowerCode = code.toLowerCase();\n if (lowerCode.includes('timeout')) {return 'timeout';}\n if (lowerCode.includes('econnrefused')) {return 'network';}\n if (lowerCode.includes('econnreset')) {return 'network';}\n if (lowerCode.includes('enotfound')) {return 'network';}\n }\n }\n\n return 'unknown';\n}\n\n/**\n * Check if an error is a rate limit error (429).\n */\nexport function isRateLimitError(error: unknown): boolean {\n return classifyError(error) === 'rate_limit';\n}\n\n/**\n * Check if an error is retryable.\n *\n * @param error - Error to check\n * @param retryableTypes - Types that should be retried\n */\nexport function isRetryableError(\n error: unknown,\n retryableTypes: ErrorType[] = ['rate_limit', 'server_error', 'timeout', 'network']\n): boolean {\n const errorType = classifyError(error);\n return retryableTypes.includes(errorType);\n}\n\n/**\n * Extract retry-after hint from error if available.\n *\n * @param error - Error to extract hint from\n * @returns Milliseconds to wait, or undefined\n */\nexport function extractRetryAfter(error: unknown): number | undefined {\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const obj = error as Record<string, unknown>;\n\n // Check common retry-after locations\n const retryAfter =\n obj.retryAfter ??\n obj['retry-after'] ??\n obj.retryAfterMs ??\n (obj.headers as Record<string, unknown> | undefined)?.['retry-after'];\n\n if (typeof retryAfter === 'number') {\n // If less than 1000, assume it's seconds\n return retryAfter < 1000 ? retryAfter * 1000 : retryAfter;\n }\n\n if (typeof retryAfter === 'string') {\n const parsed = parseInt(retryAfter, 10);\n if (!isNaN(parsed)) {\n // If less than 1000, assume it's seconds\n return parsed < 1000 ? parsed * 1000 : parsed;\n }\n }\n\n return undefined;\n}\n","/**\n * @module @kb-labs/core-resource-broker/retry/retry-strategy\n * Exponential backoff retry strategy with jitter.\n */\n\nimport type { RetryConfig, ErrorType } from '../types.js';\nimport { DEFAULT_RETRY_CONFIG } from '../types.js';\nimport { classifyError, extractRetryAfter, isRetryableError } from './error-classifier.js';\n\n/**\n * Result of a retry decision.\n */\nexport interface RetryDecision {\n /** Whether to retry */\n shouldRetry: boolean;\n\n /** Delay before retry (ms) */\n delayMs: number;\n\n /** Error classification */\n errorType: ErrorType;\n\n /** Current attempt number (0-indexed) */\n attempt: number;\n\n /** Maximum attempts allowed */\n maxAttempts: number;\n}\n\n/**\n * Calculate delay with exponential backoff and jitter.\n *\n * Formula: min(maxDelay, baseDelay * 2^attempt) * (1 + random * jitter)\n *\n * @param attempt - Current attempt (0-indexed)\n * @param config - Retry configuration\n * @param retryAfterHint - Optional retry-after hint from error (ms)\n * @returns Delay in milliseconds\n */\nexport function calculateBackoffDelay(\n attempt: number,\n config: RetryConfig,\n retryAfterHint?: number\n): number {\n // If we have a retry-after hint, use it (but cap at maxDelay)\n if (retryAfterHint !== undefined && retryAfterHint > 0) {\n return Math.min(retryAfterHint, config.maxDelay);\n }\n\n // Exponential backoff: baseDelay * 2^attempt\n const exponentialDelay = config.baseDelay * Math.pow(2, attempt);\n\n // Cap at maxDelay\n const cappedDelay = Math.min(exponentialDelay, config.maxDelay);\n\n // Add jitter: delay * (1 + random * jitter)\n const jitterMultiplier = 1 + Math.random() * config.jitter;\n\n return Math.floor(cappedDelay * jitterMultiplier);\n}\n\n/**\n * Decide whether to retry based on error and attempt count.\n *\n * @param error - The error that occurred\n * @param attempt - Current attempt (0-indexed)\n * @param config - Retry configuration\n * @returns Retry decision with delay\n *\n * @example\n * ```typescript\n * const decision = shouldRetry(error, 0, config);\n *\n * if (decision.shouldRetry) {\n * await sleep(decision.delayMs);\n * // retry...\n * } else {\n * throw error;\n * }\n * ```\n */\nexport function shouldRetry(\n error: unknown,\n attempt: number,\n config: Partial<RetryConfig> = {}\n): RetryDecision {\n const fullConfig: RetryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n const errorType = classifyError(error);\n const isRetryable = isRetryableError(error, fullConfig.retryableErrors);\n const hasAttemptsLeft = attempt < fullConfig.maxRetries;\n\n const shouldRetryNow = isRetryable && hasAttemptsLeft;\n\n // Calculate delay only if we're going to retry\n let delayMs = 0;\n if (shouldRetryNow) {\n const retryAfterHint = extractRetryAfter(error);\n\n // For rate limit errors, use longer base delay\n if (errorType === 'rate_limit') {\n const rateLimitConfig: RetryConfig = {\n ...fullConfig,\n baseDelay: Math.max(fullConfig.baseDelay, 5000), // At least 5s for rate limits\n };\n delayMs = calculateBackoffDelay(attempt, rateLimitConfig, retryAfterHint);\n } else {\n delayMs = calculateBackoffDelay(attempt, fullConfig, retryAfterHint);\n }\n }\n\n return {\n shouldRetry: shouldRetryNow,\n delayMs,\n errorType,\n attempt,\n maxAttempts: fullConfig.maxRetries,\n };\n}\n\n/**\n * Execute a function with retry logic.\n *\n * @param fn - Function to execute\n * @param config - Retry configuration\n * @returns Result of the function\n * @throws Last error if all retries exhausted\n *\n * @example\n * ```typescript\n * const result = await withRetry(\n * async () => {\n * return await llm.complete(prompt);\n * },\n * { maxRetries: 3, baseDelay: 1000 }\n * );\n * ```\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config: Partial<RetryConfig> = {}\n): Promise<{ result: T; attempts: number }> {\n const fullConfig: RetryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n let lastError: unknown;\n let attempts = 0;\n\n for (let attempt = 0; attempt <= fullConfig.maxRetries; attempt++) {\n attempts = attempt + 1;\n\n try {\n const result = await fn();\n return { result, attempts };\n } catch (error) {\n lastError = error;\n\n const decision = shouldRetry(error, attempt, fullConfig);\n\n if (!decision.shouldRetry) {\n break;\n }\n\n // Wait before retry\n await sleep(decision.delayMs);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Sleep for a specified duration.\n *\n * @param ms - Milliseconds to sleep\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\n/**\n * Create a retry configuration for rate-limited APIs.\n *\n * @param maxRetries - Maximum retry attempts (default: 5)\n * @returns Retry config optimized for rate limits\n */\nexport function createRateLimitRetryConfig(maxRetries = 5): RetryConfig {\n return {\n maxRetries,\n baseDelay: 5000, // Start with 5s for rate limits\n maxDelay: 60000, // Cap at 1 minute\n jitter: 0.2, // 20% jitter for distributed systems\n retryableErrors: ['rate_limit', 'server_error', 'timeout', 'network'],\n };\n}\n\n/**\n * Create a retry configuration for quick operations.\n *\n * @param maxRetries - Maximum retry attempts (default: 3)\n * @returns Retry config with fast retries\n */\nexport function createQuickRetryConfig(maxRetries = 3): RetryConfig {\n return {\n maxRetries,\n baseDelay: 500, // Start with 500ms\n maxDelay: 5000, // Cap at 5s\n jitter: 0.1, // 10% jitter\n retryableErrors: ['server_error', 'timeout', 'network'],\n };\n}\n","/**\n * @module @kb-labs/core-resource-broker/broker/resource-broker\n * Main ResourceBroker implementation - coordinates queues, rate limiting, and execution.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type {\n IResourceBroker,\n ResourceConfig,\n ResourceRequest,\n ResourceResponse,\n ResourceBrokerStats,\n ResourceStats,\n RateLimitBackend,\n RateLimitConfig,\n QueueItem,\n TryAcquireOptions,\n TryAcquireResult,\n} from '../types.js';\nimport { DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RETRY_CONFIG } from '../types.js';\nimport { PriorityQueue } from '../queue/priority-queue.js';\nimport { getRateLimitConfig } from '../rate-limit/presets.js';\nimport { shouldRetry, sleep } from '../retry/retry-strategy.js';\n\n/**\n * Internal resource registration with resolved config.\n */\ninterface RegisteredResource {\n config: ResourceConfig;\n rateLimits: RateLimitConfig;\n /** True when the resource was created via `registerLimit` (pressure-only, no queue). */\n limitOnly: boolean;\n stats: {\n totalRequests: number;\n totalSuccess: number;\n totalErrors: number;\n totalWaitTime: number;\n totalProcessingTime: number;\n };\n}\n\n/**\n * ResourceBroker - Centralized coordinator for heavy platform resources.\n *\n * Features:\n * - Priority queue (high/normal/low)\n * - Rate limiting with configurable backend (in-memory or distributed)\n * - Automatic retry with exponential backoff\n * - Graceful shutdown\n * - Per-resource statistics\n *\n * The platform doesn't know about plugins - only manages resources.\n * Any caller can enqueue requests with appropriate priority.\n *\n * @example\n * ```typescript\n * const backend = new InMemoryRateLimitBackend();\n * const broker = new ResourceBroker(backend);\n *\n * // Register resources\n * broker.register('llm', {\n * rateLimits: 'openai-tier-2',\n * executor: (op, args) => llmAdapter[op](...args),\n * });\n *\n * // Enqueue request\n * const response = await broker.enqueue({\n * resource: 'llm',\n * operation: 'complete',\n * args: [prompt, options],\n * priority: 'high',\n * estimatedTokens: 1000,\n * });\n * ```\n */\nexport class ResourceBroker implements IResourceBroker {\n private resources = new Map<string, RegisteredResource>();\n private queue = new PriorityQueue();\n private processing = false;\n private shuttingDown = false;\n private startTime = Date.now();\n\n /**\n * Active processing count per resource (for concurrent limit tracking).\n */\n private activeProcessing = new Map<string, number>();\n\n constructor(private rateLimitBackend: RateLimitBackend) {}\n\n /**\n * Register a resource with its configuration.\n *\n * @param resource - Resource identifier ('llm', 'embeddings', 'vectorStore')\n * @param config - Resource configuration including executor\n */\n register(resource: string, config: ResourceConfig): void {\n // Resolve rate limits (preset name or config object)\n const rateLimits =\n typeof config.rateLimits === 'string'\n ? getRateLimitConfig(config.rateLimits)\n : config.rateLimits ?? DEFAULT_RATE_LIMIT_CONFIG;\n\n this.resources.set(resource, {\n config,\n rateLimits,\n limitOnly: false,\n stats: {\n totalRequests: 0,\n totalSuccess: 0,\n totalErrors: 0,\n totalWaitTime: 0,\n totalProcessingTime: 0,\n },\n });\n\n this.activeProcessing.set(resource, 0);\n }\n\n /**\n * Register a resource for limit-only usage (no executor, no queue).\n *\n * The resource can only be used via `tryAcquire`. Calls to `enqueue` on\n * a limit-only resource resolve with `{ success: false, error }`.\n */\n registerLimit(resource: string, rateLimits: RateLimitConfig | string): void {\n const resolved =\n typeof rateLimits === 'string'\n ? getRateLimitConfig(rateLimits)\n : rateLimits;\n\n this.resources.set(resource, {\n config: {\n rateLimits,\n executor: async () => {\n throw new Error(\n `Cannot execute on limit-only resource '${resource}' ` +\n `(registered via registerLimit)`\n );\n },\n },\n rateLimits: resolved,\n limitOnly: true,\n stats: {\n totalRequests: 0,\n totalSuccess: 0,\n totalErrors: 0,\n totalWaitTime: 0,\n totalProcessingTime: 0,\n },\n });\n\n this.activeProcessing.set(resource, 0);\n }\n\n /**\n * Enqueue a request for execution.\n *\n * @param request - Resource request (without id and createdAt)\n * @returns Promise that resolves with response when execution completes\n */\n enqueue<T>(\n request: Omit<ResourceRequest, 'id' | 'createdAt'>\n ): Promise<ResourceResponse<T>> {\n if (this.shuttingDown) {\n return Promise.resolve({\n success: false,\n error: new Error('ResourceBroker is shutting down'),\n retries: 0,\n waitTime: 0,\n processingTime: 0,\n totalTime: 0,\n });\n }\n\n const registered = this.resources.get(request.resource);\n if (!registered) {\n return Promise.resolve({\n success: false,\n error: new Error(`Resource not registered: ${request.resource}`),\n retries: 0,\n waitTime: 0,\n processingTime: 0,\n totalTime: 0,\n });\n }\n\n if (registered.limitOnly) {\n return Promise.resolve({\n success: false,\n error: new Error(\n `Cannot enqueue on limit-only resource '${request.resource}' ` +\n `(registered via registerLimit — use tryAcquire instead)`\n ),\n retries: 0,\n waitTime: 0,\n processingTime: 0,\n totalTime: 0,\n });\n }\n\n // Create full request\n const fullRequest: ResourceRequest = {\n ...request,\n id: randomUUID(),\n createdAt: Date.now(),\n timeout: request.timeout ?? registered.config.timeout ?? 60000,\n maxRetries: request.maxRetries ?? registered.config.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n\n // Create promise that will be resolved when execution completes\n return new Promise<ResourceResponse<T>>((resolve, reject) => {\n const item: QueueItem = {\n request: fullRequest,\n resolve: resolve as (response: ResourceResponse) => void,\n reject,\n enqueuedAt: Date.now(),\n };\n\n this.queue.enqueue(item);\n registered.stats.totalRequests++;\n\n // Start processing if not already running\n this.processQueue();\n });\n }\n\n /**\n * Atomically check and reserve rate-limit capacity without queueing.\n *\n * Use for HTTP-style \"check + reject\" pressure control. On `allowed=true`,\n * the caller MUST invoke `result.release()` once the work is done. On\n * `allowed=false`, `release` is a no-op so callers can use the\n * unconditional `try { ... } finally { result.release() }` pattern.\n *\n * Throws if the resource has not been registered (programming error,\n * distinct from a rate-limit decision). Returns `{ allowed: false, release: noop }`\n * after `shutdown()`.\n */\n async tryAcquire(\n resource: string,\n opts?: TryAcquireOptions\n ): Promise<TryAcquireResult> {\n const noopRelease = async (): Promise<void> => {};\n\n if (this.shuttingDown) {\n return {\n allowed: false,\n release: noopRelease,\n };\n }\n\n const registered = this.resources.get(resource);\n if (!registered) {\n throw new Error(`Resource not registered: ${resource}`);\n }\n\n const tokens = opts?.tokens ?? 0;\n const result = await this.rateLimitBackend.acquire(\n resource,\n tokens,\n registered.rateLimits\n );\n\n if (!result.allowed) {\n return { ...result, release: noopRelease };\n }\n\n const currentActive = this.activeProcessing.get(resource) ?? 0;\n this.activeProcessing.set(resource, currentActive + 1);\n\n let released = false;\n const release = async (): Promise<void> => {\n if (released) {return;}\n released = true;\n await this.rateLimitBackend.release(resource);\n const active = this.activeProcessing.get(resource) ?? 1;\n this.activeProcessing.set(resource, Math.max(0, active - 1));\n };\n\n return { ...result, release };\n }\n\n /**\n * Process queue items continuously.\n */\n private async processQueue(): Promise<void> {\n // Avoid multiple concurrent processors\n if (this.processing) {\n return;\n }\n\n this.processing = true;\n\n try {\n while (!this.queue.isEmpty() && !this.shuttingDown) {\n const item = this.queue.peek();\n if (!item) {break;}\n\n const registered = this.resources.get(item.request.resource);\n if (!registered) {\n // Resource was unregistered - reject and move on\n this.queue.dequeue();\n item.reject(new Error(`Resource not registered: ${item.request.resource}`));\n continue;\n }\n\n // Check rate limits\n const tokens = item.request.estimatedTokens ?? 0;\n const acquireResult = await this.rateLimitBackend.acquire(\n item.request.resource,\n tokens,\n registered.rateLimits\n );\n\n if (!acquireResult.allowed) {\n // Wait and try again\n await sleep(acquireResult.waitTimeMs ?? 100);\n continue;\n }\n\n // Dequeue and process\n this.queue.dequeue();\n\n // Track active processing\n const currentActive = this.activeProcessing.get(item.request.resource) ?? 0;\n this.activeProcessing.set(item.request.resource, currentActive + 1);\n\n // Process in background (don't block queue processing)\n this.executeItem(item, registered).catch(() => {\n // Errors are handled in executeItem\n });\n }\n } finally {\n this.processing = false;\n\n // Check if there are more items (could have been added during processing)\n if (!this.queue.isEmpty() && !this.shuttingDown) {\n // Schedule next processing cycle\n setImmediate(() => this.processQueue());\n }\n }\n }\n\n /**\n * Execute a single queue item with retry logic.\n */\n private async executeItem(\n item: QueueItem,\n registered: RegisteredResource\n ): Promise<void> {\n const startTime = Date.now();\n const waitTime = startTime - item.enqueuedAt;\n\n let retries = 0;\n let lastError: Error | undefined;\n\n const retryConfig = {\n maxRetries: item.request.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n baseDelay: registered.config.baseDelay ?? DEFAULT_RETRY_CONFIG.baseDelay,\n maxDelay: registered.config.maxDelay ?? DEFAULT_RETRY_CONFIG.maxDelay,\n jitter: DEFAULT_RETRY_CONFIG.jitter,\n retryableErrors: DEFAULT_RETRY_CONFIG.retryableErrors,\n };\n\n try {\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n // Create timeout promise\n const timeoutMs = item.request.timeout ?? 60000;\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Request timeout after ${timeoutMs}ms`)), timeoutMs);\n });\n\n // Execute operation\n const executionPromise = registered.config.executor(\n item.request.operation,\n item.request.args\n );\n\n const result = await Promise.race([executionPromise, timeoutPromise]);\n\n // Success\n const endTime = Date.now();\n const processingTime = endTime - startTime;\n\n registered.stats.totalSuccess++;\n registered.stats.totalWaitTime += waitTime;\n registered.stats.totalProcessingTime += processingTime;\n\n item.resolve({\n success: true,\n data: result,\n retries,\n waitTime,\n processingTime,\n totalTime: endTime - item.enqueuedAt,\n });\n\n return;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n retries = attempt;\n\n const decision = shouldRetry(error, attempt, retryConfig);\n\n if (!decision.shouldRetry) {\n break;\n }\n\n // Wait before retry\n await sleep(decision.delayMs);\n\n // Re-acquire rate limit capacity for retry\n const tokens = item.request.estimatedTokens ?? 0;\n const acquireResult = await this.rateLimitBackend.acquire(\n item.request.resource,\n tokens,\n registered.rateLimits\n );\n\n if (!acquireResult.allowed && acquireResult.waitTimeMs) {\n await sleep(acquireResult.waitTimeMs);\n }\n }\n }\n\n // All retries exhausted\n const endTime = Date.now();\n const processingTime = endTime - startTime;\n\n registered.stats.totalErrors++;\n registered.stats.totalWaitTime += waitTime;\n registered.stats.totalProcessingTime += processingTime;\n\n item.resolve({\n success: false,\n error: lastError,\n retries,\n waitTime,\n processingTime,\n totalTime: endTime - item.enqueuedAt,\n });\n } finally {\n // Release rate limit slot\n await this.rateLimitBackend.release(item.request.resource);\n\n // Update active processing count\n const currentActive = this.activeProcessing.get(item.request.resource) ?? 1;\n this.activeProcessing.set(item.request.resource, Math.max(0, currentActive - 1));\n }\n }\n\n /**\n * Get broker statistics.\n */\n getStats(): ResourceBrokerStats {\n const resources: Record<string, ResourceStats> = {};\n let totalRequests = 0;\n let totalSuccess = 0;\n let totalErrors = 0;\n\n for (const [resourceName, registered] of this.resources) {\n const queueByPriority = this.queue.sizeByPriority();\n const queueSize = this.queue.sizeByResource(resourceName);\n const activeRequests = this.activeProcessing.get(resourceName) ?? 0;\n\n // Get rate limit stats (synchronously create placeholder, async update later)\n const rateLimitStats = {\n resource: resourceName,\n tokensThisMinute: 0,\n requestsThisMinute: 0,\n requestsThisSecond: 0,\n activeRequests,\n totalRequests: registered.stats.totalRequests,\n totalTokens: 0,\n waitCount: 0,\n totalWaitTime: registered.stats.totalWaitTime,\n };\n\n const avgWaitTime =\n registered.stats.totalRequests > 0\n ? registered.stats.totalWaitTime / registered.stats.totalRequests\n : 0;\n\n const avgProcessingTime =\n registered.stats.totalRequests > 0\n ? registered.stats.totalProcessingTime / registered.stats.totalRequests\n : 0;\n\n resources[resourceName] = {\n rateLimits: rateLimitStats,\n queueSize,\n queueByPriority,\n totalRequests: registered.stats.totalRequests,\n totalSuccess: registered.stats.totalSuccess,\n totalErrors: registered.stats.totalErrors,\n avgWaitTime,\n avgProcessingTime,\n };\n\n totalRequests += registered.stats.totalRequests;\n totalSuccess += registered.stats.totalSuccess;\n totalErrors += registered.stats.totalErrors;\n }\n\n return {\n resources,\n totalRequests,\n totalSuccess,\n totalErrors,\n queueSize: this.queue.size(),\n uptime: Date.now() - this.startTime,\n };\n }\n\n /**\n * Graceful shutdown - drain queues and stop processing.\n *\n * @param timeoutMs - Maximum time to wait for drain (default: 30000)\n */\n async shutdown(timeoutMs = 30000): Promise<void> {\n this.shuttingDown = true;\n\n const startTime = Date.now();\n\n // Wait for queue to drain or timeout\n while (!this.queue.isEmpty() && Date.now() - startTime < timeoutMs) {\n await sleep(100);\n }\n\n // Reject remaining items\n const remaining = this.queue.clear();\n for (const item of remaining) {\n item.resolve({\n success: false,\n error: new Error('ResourceBroker shutdown'),\n retries: 0,\n waitTime: Date.now() - item.enqueuedAt,\n processingTime: 0,\n totalTime: Date.now() - item.enqueuedAt,\n });\n }\n }\n\n /**\n * Check if broker is shutting down.\n */\n isShuttingDown(): boolean {\n return this.shuttingDown;\n }\n\n /**\n * Get registered resource names.\n */\n getRegisteredResources(): string[] {\n return Array.from(this.resources.keys());\n }\n\n /**\n * Check if a resource is registered.\n */\n hasResource(resource: string): boolean {\n return this.resources.has(resource);\n }\n\n /**\n * Unregister a resource.\n * Note: Pending requests for this resource will fail.\n */\n unregister(resource: string): void {\n this.resources.delete(resource);\n this.activeProcessing.delete(resource);\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/rate-limit/in-memory-backend\n * In-memory implementation of RateLimitBackend for single-process deployments.\n */\n\nimport type {\n RateLimitBackend,\n RateLimitConfig,\n RateLimitStats,\n AcquireResult,\n} from '../types.js';\n\n/**\n * Internal state for a single resource.\n */\ninterface ResourceState {\n // Window tracking\n tokensThisMinute: number;\n requestsThisMinute: number;\n requestsThisSecond: number;\n activeRequests: number;\n\n // Window timestamps\n minuteWindowStart: number;\n secondWindowStart: number;\n\n // Stats\n totalRequests: number;\n totalTokens: number;\n waitCount: number;\n totalWaitTime: number;\n}\n\n/**\n * In-memory rate limit backend.\n *\n * Uses sliding window approach for TPM/RPM/RPS tracking.\n * Suitable for single-process deployments.\n *\n * @example\n * ```typescript\n * const backend = new InMemoryRateLimitBackend();\n *\n * const result = await backend.acquire('llm', 1000, {\n * tokensPerMinute: 100000,\n * requestsPerMinute: 1000,\n * });\n *\n * if (result.allowed) {\n * // Execute request\n * await backend.release('llm');\n * } else {\n * // Wait and retry\n * await sleep(result.waitTimeMs);\n * }\n * ```\n */\nexport class InMemoryRateLimitBackend implements RateLimitBackend {\n private states = new Map<string, ResourceState>();\n\n /**\n * Get or create state for a resource.\n */\n private getState(resource: string): ResourceState {\n let state = this.states.get(resource);\n if (!state) {\n const now = Date.now();\n state = {\n tokensThisMinute: 0,\n requestsThisMinute: 0,\n requestsThisSecond: 0,\n activeRequests: 0,\n minuteWindowStart: now,\n secondWindowStart: now,\n totalRequests: 0,\n totalTokens: 0,\n waitCount: 0,\n totalWaitTime: 0,\n };\n this.states.set(resource, state);\n }\n return state;\n }\n\n /**\n * Reset windows if time has passed.\n */\n private resetWindowsIfNeeded(state: ResourceState): void {\n const now = Date.now();\n\n // Reset minute window\n if (now - state.minuteWindowStart >= 60_000) {\n state.tokensThisMinute = 0;\n state.requestsThisMinute = 0;\n state.minuteWindowStart = now;\n }\n\n // Reset second window\n if (now - state.secondWindowStart >= 1_000) {\n state.requestsThisSecond = 0;\n state.secondWindowStart = now;\n }\n }\n\n /**\n * Check if all limits allow proceeding.\n */\n private checkLimits(\n state: ResourceState,\n tokens: number,\n config: RateLimitConfig\n ): { allowed: boolean; waitTimeMs?: number } {\n const now = Date.now();\n const safetyMargin = config.safetyMargin ?? 0.9;\n\n // Apply safety margin to limits\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n const effectiveRPS = config.requestsPerSecond\n ? Math.floor(config.requestsPerSecond * safetyMargin)\n : undefined;\n\n const delays: number[] = [];\n\n // Check TPM\n if (effectiveTPM !== undefined && state.tokensThisMinute + tokens > effectiveTPM) {\n const timeUntilMinuteReset = 60_000 - (now - state.minuteWindowStart);\n delays.push(Math.max(100, timeUntilMinuteReset + 100));\n }\n\n // Check RPM\n if (effectiveRPM !== undefined && state.requestsThisMinute >= effectiveRPM) {\n const timeUntilMinuteReset = 60_000 - (now - state.minuteWindowStart);\n delays.push(Math.max(100, timeUntilMinuteReset + 100));\n }\n\n // Check RPS\n if (effectiveRPS !== undefined && state.requestsThisSecond >= effectiveRPS) {\n const timeUntilSecondReset = 1_000 - (now - state.secondWindowStart);\n delays.push(Math.max(50, timeUntilSecondReset + 50));\n }\n\n // Check concurrent requests\n if (\n config.maxConcurrentRequests !== undefined &&\n state.activeRequests >= config.maxConcurrentRequests\n ) {\n delays.push(100); // Check every 100ms for slot availability\n }\n\n if (delays.length > 0) {\n return { allowed: false, waitTimeMs: Math.min(...delays) };\n }\n\n return { allowed: true };\n }\n\n /**\n * @inheritdoc\n */\n async acquire(\n resource: string,\n tokens: number,\n config: RateLimitConfig\n ): Promise<AcquireResult> {\n const state = this.getState(resource);\n this.resetWindowsIfNeeded(state);\n\n const check = this.checkLimits(state, tokens, config);\n\n if (!check.allowed) {\n state.waitCount++;\n state.totalWaitTime += check.waitTimeMs ?? 0;\n\n // Calculate remaining capacity\n const safetyMargin = config.safetyMargin ?? 0.9;\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n\n return {\n allowed: false,\n waitTimeMs: check.waitTimeMs,\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - state.tokensThisMinute)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - state.requestsThisMinute)\n : undefined,\n activeRequests: state.activeRequests,\n };\n }\n\n // Reserve capacity\n state.tokensThisMinute += tokens;\n state.requestsThisMinute++;\n state.requestsThisSecond++;\n state.activeRequests++;\n state.totalRequests++;\n state.totalTokens += tokens;\n\n // Calculate remaining capacity\n const safetyMargin = config.safetyMargin ?? 0.9;\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n\n return {\n allowed: true,\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - state.tokensThisMinute)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - state.requestsThisMinute)\n : undefined,\n activeRequests: state.activeRequests,\n };\n }\n\n /**\n * @inheritdoc\n */\n async release(resource: string): Promise<void> {\n const state = this.states.get(resource);\n if (state) {\n state.activeRequests = Math.max(0, state.activeRequests - 1);\n }\n }\n\n /**\n * @inheritdoc\n */\n async getStats(resource: string): Promise<RateLimitStats> {\n const state = this.getState(resource);\n this.resetWindowsIfNeeded(state);\n\n return {\n resource,\n tokensThisMinute: state.tokensThisMinute,\n requestsThisMinute: state.requestsThisMinute,\n requestsThisSecond: state.requestsThisSecond,\n activeRequests: state.activeRequests,\n totalRequests: state.totalRequests,\n totalTokens: state.totalTokens,\n waitCount: state.waitCount,\n totalWaitTime: state.totalWaitTime,\n };\n }\n\n /**\n * @inheritdoc\n */\n async reset(resource: string): Promise<void> {\n this.states.delete(resource);\n }\n\n /**\n * Reset all resources.\n */\n resetAll(): void {\n this.states.clear();\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/rate-limit/state-broker-backend\n * Distributed rate limit backend using StateBroker.\n *\n * Enables horizontal scaling by storing rate counters in a shared StateBroker\n * (HTTP daemon or future Redis backend).\n */\n\nimport type { StateBroker } from '@kb-labs/core-state-broker';\nimport type {\n RateLimitBackend,\n RateLimitConfig,\n RateLimitStats,\n AcquireResult,\n} from '../types.js';\n\n/**\n * State stored in StateBroker for each resource window.\n */\ninterface WindowState {\n tokens: number;\n requests: number;\n activeRequests: number;\n updatedAt: number;\n}\n\n/**\n * Cumulative stats stored in StateBroker.\n */\ninterface CumulativeStats {\n totalRequests: number;\n totalTokens: number;\n waitCount: number;\n totalWaitTime: number;\n}\n\n/**\n * Distributed rate limit backend using StateBroker.\n *\n * Key patterns:\n * - `ratelimit:{resource}:minute:{YYYY-MM-DDTHH:MM}` - Minute window counters\n * - `ratelimit:{resource}:second:{YYYY-MM-DDTHH:MM:SS}` - Second window counters\n * - `ratelimit:{resource}:active` - Active concurrent requests\n * - `ratelimit:{resource}:stats` - Cumulative statistics\n *\n * TTL strategy:\n * - Minute windows: 120s TTL (allows for clock skew)\n * - Second windows: 10s TTL\n * - Active counter: No TTL (managed explicitly)\n * - Stats: No TTL (persisted)\n *\n * @example\n * ```typescript\n * import { createStateBroker } from '@kb-labs/core-state-broker';\n *\n * const broker = createStateBroker({ backend: 'http', url: 'http://localhost:7777' });\n * const backend = new StateBrokerRateLimitBackend(broker);\n *\n * // Now rate limits are coordinated across all processes using the same daemon\n * ```\n */\nexport class StateBrokerRateLimitBackend implements RateLimitBackend {\n constructor(private broker: StateBroker) {}\n\n /**\n * Get current minute window key.\n */\n private getMinuteKey(resource: string): string {\n const window = new Date().toISOString().slice(0, 16); // YYYY-MM-DDTHH:MM\n return `ratelimit:${resource}:minute:${window}`;\n }\n\n /**\n * Get current second window key.\n */\n private getSecondKey(resource: string): string {\n const window = new Date().toISOString().slice(0, 19); // YYYY-MM-DDTHH:MM:SS\n return `ratelimit:${resource}:second:${window}`;\n }\n\n /**\n * Get active requests key.\n */\n private getActiveKey(resource: string): string {\n return `ratelimit:${resource}:active`;\n }\n\n /**\n * Get stats key.\n */\n private getStatsKey(resource: string): string {\n return `ratelimit:${resource}:stats`;\n }\n\n /**\n * Get or initialize window state.\n */\n private async getWindowState(key: string): Promise<WindowState> {\n const state = await this.broker.get<WindowState>(key);\n return state ?? { tokens: 0, requests: 0, activeRequests: 0, updatedAt: Date.now() };\n }\n\n /**\n * Get or initialize stats.\n */\n private async getCumulativeStats(resource: string): Promise<CumulativeStats> {\n const stats = await this.broker.get<CumulativeStats>(this.getStatsKey(resource));\n return stats ?? { totalRequests: 0, totalTokens: 0, waitCount: 0, totalWaitTime: 0 };\n }\n\n /**\n * @inheritdoc\n */\n // eslint-disable-next-line sonarjs/cognitive-complexity\n async acquire(\n resource: string,\n tokens: number,\n config: RateLimitConfig\n ): Promise<AcquireResult> {\n const safetyMargin = config.safetyMargin ?? 0.9;\n\n // Get current state from all windows\n const [minuteState, secondState, activeCount] = await Promise.all([\n this.getWindowState(this.getMinuteKey(resource)),\n this.getWindowState(this.getSecondKey(resource)),\n this.broker.get<number>(this.getActiveKey(resource)).then(v => v ?? 0),\n ]);\n\n // Calculate effective limits\n const effectiveTPM = config.tokensPerMinute\n ? Math.floor(config.tokensPerMinute * safetyMargin)\n : undefined;\n const effectiveRPM = config.requestsPerMinute\n ? Math.floor(config.requestsPerMinute * safetyMargin)\n : undefined;\n const effectiveRPS = config.requestsPerSecond\n ? Math.floor(config.requestsPerSecond * safetyMargin)\n : undefined;\n\n // Check limits\n const delays: number[] = [];\n const now = Date.now();\n\n // Check TPM\n if (effectiveTPM && minuteState.tokens + tokens > effectiveTPM) {\n // Wait until next minute\n const secondsRemaining = 60 - new Date().getSeconds();\n delays.push(secondsRemaining * 1000 + 100);\n }\n\n // Check RPM\n if (effectiveRPM && minuteState.requests >= effectiveRPM) {\n const secondsRemaining = 60 - new Date().getSeconds();\n delays.push(secondsRemaining * 1000 + 100);\n }\n\n // Check RPS\n if (effectiveRPS && secondState.requests >= effectiveRPS) {\n const msRemaining = 1000 - new Date().getMilliseconds();\n delays.push(msRemaining + 50);\n }\n\n // Check concurrent\n if (config.maxConcurrentRequests && activeCount >= config.maxConcurrentRequests) {\n delays.push(100);\n }\n\n if (delays.length > 0) {\n // Update wait stats\n const stats = await this.getCumulativeStats(resource);\n stats.waitCount++;\n stats.totalWaitTime += Math.min(...delays);\n await this.broker.set(this.getStatsKey(resource), stats);\n\n return {\n allowed: false,\n waitTimeMs: Math.min(...delays),\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - minuteState.tokens)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - minuteState.requests)\n : undefined,\n activeRequests: activeCount,\n };\n }\n\n // Reserve capacity - update all windows atomically as possible\n const minuteKey = this.getMinuteKey(resource);\n const secondKey = this.getSecondKey(resource);\n const activeKey = this.getActiveKey(resource);\n const statsKey = this.getStatsKey(resource);\n\n // Update minute window\n const newMinuteState: WindowState = {\n tokens: minuteState.tokens + tokens,\n requests: minuteState.requests + 1,\n activeRequests: activeCount + 1,\n updatedAt: now,\n };\n await this.broker.set(minuteKey, newMinuteState, 120_000); // 2 min TTL\n\n // Update second window\n const newSecondState: WindowState = {\n tokens: secondState.tokens + tokens,\n requests: secondState.requests + 1,\n activeRequests: activeCount + 1,\n updatedAt: now,\n };\n await this.broker.set(secondKey, newSecondState, 10_000); // 10s TTL\n\n // Update active count\n await this.broker.set(activeKey, activeCount + 1);\n\n // Update cumulative stats\n const stats = await this.getCumulativeStats(resource);\n stats.totalRequests++;\n stats.totalTokens += tokens;\n await this.broker.set(statsKey, stats);\n\n return {\n allowed: true,\n tokensRemaining: effectiveTPM\n ? Math.max(0, effectiveTPM - newMinuteState.tokens)\n : undefined,\n requestsRemaining: effectiveRPM\n ? Math.max(0, effectiveRPM - newMinuteState.requests)\n : undefined,\n activeRequests: activeCount + 1,\n };\n }\n\n /**\n * @inheritdoc\n */\n async release(resource: string): Promise<void> {\n const activeKey = this.getActiveKey(resource);\n const current = await this.broker.get<number>(activeKey);\n if (current !== null && current > 0) {\n await this.broker.set(activeKey, current - 1);\n }\n }\n\n /**\n * @inheritdoc\n */\n async getStats(resource: string): Promise<RateLimitStats> {\n const [minuteState, secondState, activeCount, cumulativeStats] = await Promise.all([\n this.getWindowState(this.getMinuteKey(resource)),\n this.getWindowState(this.getSecondKey(resource)),\n this.broker.get<number>(this.getActiveKey(resource)).then(v => v ?? 0),\n this.getCumulativeStats(resource),\n ]);\n\n return {\n resource,\n tokensThisMinute: minuteState.tokens,\n requestsThisMinute: minuteState.requests,\n requestsThisSecond: secondState.requests,\n activeRequests: activeCount,\n totalRequests: cumulativeStats.totalRequests,\n totalTokens: cumulativeStats.totalTokens,\n waitCount: cumulativeStats.waitCount,\n totalWaitTime: cumulativeStats.totalWaitTime,\n };\n }\n\n /**\n * @inheritdoc\n */\n async reset(resource: string): Promise<void> {\n // Clear all keys for this resource\n await Promise.all([\n this.broker.clear(`ratelimit:${resource}:*`),\n ]);\n }\n}\n","/**\n * @module @kb-labs/core-resource-broker/wrappers/queued-llm\n * QueuedLLM - ILLM wrapper that routes requests through ResourceBroker.\n */\n\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMProtocolCapabilities,\n} from '@kb-labs/core-platform';\nimport type { IResourceBroker, ResourcePriority } from '../types.js';\nimport { estimateTokens } from '../rate-limit/presets.js';\n\n/**\n * Extended LLM options with priority.\n */\nexport interface QueuedLLMOptions extends LLMOptions {\n /** Request priority (default: 'normal') */\n priority?: ResourcePriority;\n}\n\n/**\n * ILLM wrapper that routes requests through ResourceBroker.\n *\n * Features:\n * - Transparent integration (implements ILLM interface)\n * - Automatic token estimation for rate limiting\n * - Priority support for different use cases\n * - Retry and rate limiting handled by broker\n *\n * Note: stream() bypasses the queue for real-time UX.\n *\n * @example\n * ```typescript\n * const queuedLLM = new QueuedLLM(broker, realLLM);\n *\n * // Normal request (goes through queue)\n * const response = await queuedLLM.complete(prompt);\n *\n * // High priority request\n * const response = await queuedLLM.complete(prompt, { priority: 'high' });\n *\n * // Stream (bypasses queue for real-time)\n * for await (const chunk of queuedLLM.stream(prompt)) {\n * process.stdout.write(chunk);\n * }\n * ```\n */\nexport class QueuedLLM implements ILLM {\n constructor(\n private broker: IResourceBroker,\n private realLLM: ILLM\n ) {}\n\n /**\n * Generate a completion through the queue.\n *\n * @param prompt - Text prompt\n * @param options - Optional generation options with priority\n * @returns LLM response\n * @throws Error if request fails after all retries\n */\n async complete(prompt: string, options?: QueuedLLMOptions): Promise<LLMResponse> {\n const priority: ResourcePriority = options?.priority ?? 'normal';\n const estimatedTokens = estimateTokens(prompt);\n\n // Use resource from metadata if provided (set by LLMRouter), fallback to 'llm'\n const resource = options?.metadata?.resource ?? 'llm';\n\n const response = await this.broker.enqueue<LLMResponse>({\n resource,\n operation: 'complete',\n args: [prompt, options],\n priority,\n estimatedTokens,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('LLM request failed');\n }\n\n return response.data!;\n }\n\n async getProtocolCapabilities(): Promise<LLMProtocolCapabilities> {\n if (!this.realLLM.getProtocolCapabilities) {\n return {\n cache: { supported: false },\n stream: { supported: true },\n };\n }\n return this.realLLM.getProtocolCapabilities();\n }\n\n /**\n * Stream a completion (bypasses queue for real-time UX).\n *\n * Streaming is passed through directly to the underlying LLM\n * because:\n * 1. Real-time user experience requires immediate response\n * 2. Token counting happens after streaming completes\n * 3. Rate limits are still enforced by the underlying adapter\n *\n * @param prompt - Text prompt\n * @param options - Optional generation options\n * @returns Async iterable of text chunks\n */\n stream(prompt: string, options?: LLMOptions): AsyncIterable<string> {\n // Pass through to real LLM for real-time streaming\n return this.realLLM.stream(prompt, options);\n }\n\n /**\n * Chat with native tool calling support (proxies to underlying LLM).\n * Currently NOT queued - passes through directly for simplicity.\n * TODO: Add queueing support when needed.\n */\n async chatWithTools(\n messages: LLMMessage[],\n options: LLMToolCallOptions\n ): Promise<LLMToolCallResponse> {\n // Check if underlying LLM supports chatWithTools\n if (!this.realLLM.chatWithTools) {\n throw new Error('Underlying LLM does not support chatWithTools');\n }\n\n // TODO: Route through queue for rate limiting\n // For now, pass through directly to avoid complexity\n return this.realLLM.chatWithTools(messages, options);\n }\n}\n\n/**\n * Create a QueuedLLM wrapper.\n *\n * @param broker - ResourceBroker instance\n * @param llm - Real ILLM implementation\n * @returns Wrapped ILLM that routes through broker\n */\nexport function createQueuedLLM(broker: IResourceBroker, llm: ILLM): QueuedLLM {\n return new QueuedLLM(broker, llm);\n}\n","/**\n * @module @kb-labs/core-resource-broker/wrappers/queued-embeddings\n * QueuedEmbeddings - IEmbeddings wrapper that routes requests through ResourceBroker.\n */\n\nimport type { IEmbeddings } from '@kb-labs/core-platform';\nimport type { IResourceBroker, ResourcePriority } from '../types.js';\nimport { estimateTokens, estimateBatchTokens } from '../rate-limit/presets.js';\n\n/**\n * Options for queued embeddings operations.\n */\nexport interface QueuedEmbeddingsOptions {\n /** Request priority (default: 'normal') */\n priority?: ResourcePriority;\n}\n\n/**\n * IEmbeddings wrapper that routes requests through ResourceBroker.\n *\n * Features:\n * - Transparent integration (implements IEmbeddings interface)\n * - Automatic token estimation for rate limiting\n * - Batch operations with proper token accounting\n * - Priority support for different use cases\n *\n * @example\n * ```typescript\n * const queuedEmbeddings = new QueuedEmbeddings(broker, realEmbeddings);\n *\n * // Single embedding\n * const vector = await queuedEmbeddings.embed(\"Hello world\");\n *\n * // Batch embedding\n * const vectors = await queuedEmbeddings.embedBatch([\"Hello\", \"World\"]);\n * ```\n */\nexport class QueuedEmbeddings implements IEmbeddings {\n private _priority: ResourcePriority = 'normal';\n\n constructor(\n private broker: IResourceBroker,\n private realEmbeddings: IEmbeddings\n ) {}\n\n /**\n * Get embedding dimensions from the underlying implementation.\n */\n get dimensions(): number {\n return this.realEmbeddings.dimensions;\n }\n\n /**\n * Set default priority for subsequent operations.\n *\n * @param priority - Priority level\n * @returns this for chaining\n */\n withPriority(priority: ResourcePriority): this {\n this._priority = priority;\n return this;\n }\n\n /**\n * Generate embedding vector for a single text through the queue.\n *\n * @param text - Input text\n * @returns Embedding vector\n * @throws Error if request fails after all retries\n */\n async embed(text: string): Promise<number[]> {\n const estimatedTokens = estimateTokens(text);\n\n const response = await this.broker.enqueue<number[]>({\n resource: 'embeddings',\n operation: 'embed',\n args: [text],\n priority: this._priority,\n estimatedTokens,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('Embeddings request failed');\n }\n\n return response.data!;\n }\n\n /**\n * Generate embedding vectors for multiple texts through the queue.\n *\n * @param texts - Array of input texts\n * @returns Array of embedding vectors\n * @throws Error if request fails after all retries\n */\n async embedBatch(texts: string[]): Promise<number[][]> {\n const estimatedTokens = estimateBatchTokens(texts);\n\n const response = await this.broker.enqueue<number[][]>({\n resource: 'embeddings',\n operation: 'embedBatch',\n args: [texts],\n priority: this._priority,\n estimatedTokens,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('Embeddings batch request failed');\n }\n\n return response.data!;\n }\n\n /**\n * Get the dimensions of the embeddings.\n * This method is needed for IPC/Unix Socket transport to access the dimensions property.\n */\n async getDimensions(): Promise<number> {\n return this.realEmbeddings.dimensions;\n }\n}\n\n/**\n * Create a QueuedEmbeddings wrapper.\n *\n * @param broker - ResourceBroker instance\n * @param embeddings - Real IEmbeddings implementation\n * @returns Wrapped IEmbeddings that routes through broker\n */\nexport function createQueuedEmbeddings(\n broker: IResourceBroker,\n embeddings: IEmbeddings\n): QueuedEmbeddings {\n return new QueuedEmbeddings(broker, embeddings);\n}\n","/**\n * @module @kb-labs/core-resource-broker/wrappers/queued-vector-store\n * QueuedVectorStore - IVectorStore wrapper that routes requests through ResourceBroker.\n */\n\nimport type {\n IVectorStore,\n VectorRecord,\n VectorSearchResult,\n VectorFilter,\n} from '@kb-labs/core-platform';\nimport type { IResourceBroker, ResourcePriority } from '../types.js';\n\n/**\n * Options for queued vector store operations.\n */\nexport interface QueuedVectorStoreOptions {\n /** Request priority (default: 'normal') */\n priority?: ResourcePriority;\n}\n\n/**\n * IVectorStore wrapper that routes requests through ResourceBroker.\n *\n * Features:\n * - Transparent integration (implements IVectorStore interface)\n * - Rate limiting for batch operations\n * - Priority support for different use cases\n * - Search operations prioritized over bulk upserts\n *\n * @example\n * ```typescript\n * const queuedVectorStore = new QueuedVectorStore(broker, realVectorStore);\n *\n * // Search (typically high priority)\n * const results = await queuedVectorStore.search(queryVector, 10);\n *\n * // Bulk upsert (typically normal/low priority)\n * await queuedVectorStore.upsert(vectors);\n * ```\n */\nexport class QueuedVectorStore implements IVectorStore {\n private _priority: ResourcePriority = 'normal';\n\n constructor(\n private broker: IResourceBroker,\n private realVectorStore: IVectorStore\n ) {}\n\n /**\n * Set default priority for subsequent operations.\n *\n * @param priority - Priority level\n * @returns this for chaining\n */\n withPriority(priority: ResourcePriority): this {\n this._priority = priority;\n return this;\n }\n\n /**\n * Search for similar vectors through the queue.\n *\n * @param query - Query embedding vector\n * @param limit - Maximum number of results\n * @param filter - Optional metadata filter\n * @returns Search results\n * @throws Error if request fails after all retries\n */\n async search(\n query: number[],\n limit: number,\n filter?: VectorFilter,\n namespace?: string\n ): Promise<VectorSearchResult[]> {\n const response = await this.broker.enqueue<VectorSearchResult[]>({\n resource: 'vectorStore',\n operation: 'search',\n args: [query, limit, filter, namespace],\n priority: this._priority,\n // No token estimation for vector operations\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore search failed');\n }\n\n return response.data!;\n }\n\n /**\n * Upsert vectors through the queue.\n *\n * @param vectors - Array of vector records to upsert\n * @throws Error if request fails after all retries\n */\n async upsert(vectors: VectorRecord[], namespace?: string): Promise<void> {\n const response = await this.broker.enqueue<void>({\n resource: 'vectorStore',\n operation: 'upsert',\n args: [vectors, namespace],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore upsert failed');\n }\n }\n\n /**\n * Delete vectors through the queue.\n *\n * @param ids - Array of vector IDs to delete\n * @throws Error if request fails after all retries\n */\n async delete(ids: string[], namespace?: string): Promise<void> {\n const response = await this.broker.enqueue<void>({\n resource: 'vectorStore',\n operation: 'delete',\n args: [ids, namespace],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore delete failed');\n }\n }\n\n /**\n * Get total count of vectors through the queue.\n *\n * @returns Vector count\n * @throws Error if request fails after all retries\n */\n async count(namespace?: string): Promise<number> {\n const response = await this.broker.enqueue<number>({\n resource: 'vectorStore',\n operation: 'count',\n args: [namespace],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore count failed');\n }\n\n return response.data!;\n }\n\n /**\n * Get vectors by IDs through the queue (if supported).\n *\n * @param ids - Array of vector IDs to retrieve\n * @returns Array of vector records\n * @throws Error if request fails or method not supported\n */\n async get(ids: string[], namespace?: string): Promise<VectorRecord[]> {\n if (!this.realVectorStore.get) {\n throw new Error('VectorStore.get() not supported by underlying implementation');\n }\n\n const response = await this.broker.enqueue<VectorRecord[]>({\n resource: 'vectorStore',\n operation: 'get',\n args: [ids, namespace],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore get failed');\n }\n\n return response.data!;\n }\n\n /**\n * Query vectors by filter through the queue (if supported).\n *\n * @param filter - Metadata filter to apply\n * @returns Array of matching vector records\n * @throws Error if request fails or method not supported\n */\n async query(filter: VectorFilter, namespace?: string): Promise<VectorRecord[]> {\n if (!this.realVectorStore.query) {\n throw new Error('VectorStore.query() not supported by underlying implementation');\n }\n\n const response = await this.broker.enqueue<VectorRecord[]>({\n resource: 'vectorStore',\n operation: 'query',\n args: [filter, namespace],\n priority: this._priority,\n });\n\n if (!response.success) {\n throw response.error ?? new Error('VectorStore query failed');\n }\n\n return response.data!;\n }\n}\n\n/**\n * Create a QueuedVectorStore wrapper.\n *\n * @param broker - ResourceBroker instance\n * @param vectorStore - Real IVectorStore implementation\n * @returns Wrapped IVectorStore that routes through broker\n */\nexport function createQueuedVectorStore(\n broker: IResourceBroker,\n vectorStore: IVectorStore\n): QueuedVectorStore {\n return new QueuedVectorStore(broker, vectorStore);\n}\n","/**\n * @module @kb-labs/core-resource-broker/wrappers/queued-notifier-channel\n * QueuedNotifierChannel — INotifierChannel wrapper that routes send() through ResourceBroker.\n *\n * Provides rate-limiting, retry with exponential backoff, priority queue, and\n * distributed quota (via StateBroker) for free — same as QueuedLLM.\n */\n\nimport type { INotifierChannel, NotificationCapability, NotificationEvent } from '@kb-labs/core-platform';\nimport type { IResourceBroker, ResourcePriority } from '../types.js';\n\nfunction severityToPriority(severity: NotificationEvent['severity']): ResourcePriority {\n if (severity === 'critical') {return 'high';}\n if (severity === 'warn') {return 'normal';}\n return 'low';\n}\n\nexport class QueuedNotifierChannel implements INotifierChannel {\n constructor(\n private broker: IResourceBroker,\n private channel: INotifierChannel\n ) {}\n\n get id(): string { return this.channel.id; }\n get capabilities(): NotificationCapability[] { return this.channel.capabilities; }\n isAvailable(): boolean { return this.channel.isAvailable(); }\n\n async send(event: NotificationEvent): Promise<void> {\n const response = await this.broker.enqueue<void>({\n resource: `notifier:${this.channel.id}`,\n operation: 'send',\n args: [event],\n priority: severityToPriority(event.severity),\n estimatedTokens: 1,\n });\n\n if (!response.success) {\n throw response.error ?? new Error(`Notifier channel '${this.channel.id}' send failed`);\n }\n }\n}\n\nexport function createQueuedNotifierChannel(\n broker: IResourceBroker,\n channel: INotifierChannel\n): QueuedNotifierChannel {\n return new QueuedNotifierChannel(broker, channel);\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kb-labs/core-resource-broker",
3
3
  "description": "Centralized resource broker for queue management, rate limiting, and retry logic",
4
- "version": "2.94.0",
4
+ "version": "2.98.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -16,16 +16,17 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@kb-labs/core-platform": "2.94.0",
20
- "@kb-labs/core-state-broker": "2.94.0"
19
+ "@kb-labs/core-state-broker": "2.98.0",
20
+ "@kb-labs/core-platform": "2.98.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^24.3.3",
24
24
  "rimraf": "^6.0.1",
25
25
  "tsup": "^8.5.0",
26
26
  "typescript": "^5.6.3",
27
- "vitest": "^3.2.4",
28
- "@kb-labs/devkit": "2.94.0"
27
+ "vitest": "^3.2.6",
28
+ "@kb-labs/shared-testing": "2.98.0",
29
+ "@kb-labs/devkit": "2.98.0"
29
30
  },
30
31
  "engines": {
31
32
  "node": ">=20.0.0",