glancey 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +435 -0
- package/dist/__tests__/ast-chunker.test.d.ts +2 -0
- package/dist/__tests__/ast-chunker.test.d.ts.map +1 -0
- package/dist/__tests__/ast-chunker.test.js +307 -0
- package/dist/__tests__/ast-chunker.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +242 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/dashboard/beads.test.d.ts +2 -0
- package/dist/__tests__/dashboard/beads.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard/beads.test.js +151 -0
- package/dist/__tests__/dashboard/beads.test.js.map +1 -0
- package/dist/__tests__/dashboard/index.test.d.ts +2 -0
- package/dist/__tests__/dashboard/index.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard/index.test.js +116 -0
- package/dist/__tests__/dashboard/index.test.js.map +1 -0
- package/dist/__tests__/dashboard/routes.test.d.ts +2 -0
- package/dist/__tests__/dashboard/routes.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard/routes.test.js +125 -0
- package/dist/__tests__/dashboard/routes.test.js.map +1 -0
- package/dist/__tests__/dashboard/server.test.d.ts +2 -0
- package/dist/__tests__/dashboard/server.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard/server.test.js +75 -0
- package/dist/__tests__/dashboard/server.test.js.map +1 -0
- package/dist/__tests__/dashboard/state.test.d.ts +2 -0
- package/dist/__tests__/dashboard/state.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard/state.test.js +124 -0
- package/dist/__tests__/dashboard/state.test.js.map +1 -0
- package/dist/__tests__/dashboard/token-tracking.test.d.ts +2 -0
- package/dist/__tests__/dashboard/token-tracking.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard/token-tracking.test.js +315 -0
- package/dist/__tests__/dashboard/token-tracking.test.js.map +1 -0
- package/dist/__tests__/embeddings/factory.test.d.ts +2 -0
- package/dist/__tests__/embeddings/factory.test.d.ts.map +1 -0
- package/dist/__tests__/embeddings/factory.test.js +157 -0
- package/dist/__tests__/embeddings/factory.test.js.map +1 -0
- package/dist/__tests__/embeddings/gemini.test.d.ts +2 -0
- package/dist/__tests__/embeddings/gemini.test.d.ts.map +1 -0
- package/dist/__tests__/embeddings/gemini.test.js +178 -0
- package/dist/__tests__/embeddings/gemini.test.js.map +1 -0
- package/dist/__tests__/embeddings/ollama.test.d.ts +2 -0
- package/dist/__tests__/embeddings/ollama.test.d.ts.map +1 -0
- package/dist/__tests__/embeddings/ollama.test.js +273 -0
- package/dist/__tests__/embeddings/ollama.test.js.map +1 -0
- package/dist/__tests__/embeddings/rate-limiter.test.d.ts +2 -0
- package/dist/__tests__/embeddings/rate-limiter.test.d.ts.map +1 -0
- package/dist/__tests__/embeddings/rate-limiter.test.js +163 -0
- package/dist/__tests__/embeddings/rate-limiter.test.js.map +1 -0
- package/dist/__tests__/embeddings/retry.test.d.ts +2 -0
- package/dist/__tests__/embeddings/retry.test.d.ts.map +1 -0
- package/dist/__tests__/embeddings/retry.test.js +334 -0
- package/dist/__tests__/embeddings/retry.test.js.map +1 -0
- package/dist/__tests__/embeddings/types.test.d.ts +2 -0
- package/dist/__tests__/embeddings/types.test.d.ts.map +1 -0
- package/dist/__tests__/embeddings/types.test.js +31 -0
- package/dist/__tests__/embeddings/types.test.js.map +1 -0
- package/dist/__tests__/mocks/embedding-backend.mock.d.ts +10 -0
- package/dist/__tests__/mocks/embedding-backend.mock.d.ts.map +1 -0
- package/dist/__tests__/mocks/embedding-backend.mock.js +39 -0
- package/dist/__tests__/mocks/embedding-backend.mock.js.map +1 -0
- package/dist/__tests__/mocks/fetch.mock.d.ts +49 -0
- package/dist/__tests__/mocks/fetch.mock.d.ts.map +1 -0
- package/dist/__tests__/mocks/fetch.mock.js +102 -0
- package/dist/__tests__/mocks/fetch.mock.js.map +1 -0
- package/dist/__tests__/mocks/lancedb.mock.d.ts +38 -0
- package/dist/__tests__/mocks/lancedb.mock.d.ts.map +1 -0
- package/dist/__tests__/mocks/lancedb.mock.js +63 -0
- package/dist/__tests__/mocks/lancedb.mock.js.map +1 -0
- package/dist/__tests__/search/clustering.test.d.ts +2 -0
- package/dist/__tests__/search/clustering.test.d.ts.map +1 -0
- package/dist/__tests__/search/clustering.test.js +230 -0
- package/dist/__tests__/search/clustering.test.js.map +1 -0
- package/dist/__tests__/search/hybrid-search.test.d.ts +2 -0
- package/dist/__tests__/search/hybrid-search.test.d.ts.map +1 -0
- package/dist/__tests__/search/hybrid-search.test.js +279 -0
- package/dist/__tests__/search/hybrid-search.test.js.map +1 -0
- package/dist/__tests__/search/indexer.test.d.ts +2 -0
- package/dist/__tests__/search/indexer.test.d.ts.map +1 -0
- package/dist/__tests__/search/indexer.test.js +1305 -0
- package/dist/__tests__/search/indexer.test.js.map +1 -0
- package/dist/__tests__/search/tree-sitter-chunker.test.d.ts +2 -0
- package/dist/__tests__/search/tree-sitter-chunker.test.d.ts.map +1 -0
- package/dist/__tests__/search/tree-sitter-chunker.test.js +228 -0
- package/dist/__tests__/search/tree-sitter-chunker.test.js.map +1 -0
- package/dist/__tests__/setup.d.ts +2 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +11 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/tools/clustering-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/clustering-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/clustering-handlers.test.js +286 -0
- package/dist/__tests__/tools/clustering-handlers.test.js.map +1 -0
- package/dist/__tests__/tools/commit-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/commit-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/commit-handlers.test.js +153 -0
- package/dist/__tests__/tools/commit-handlers.test.js.map +1 -0
- package/dist/__tests__/tools/index-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/index-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/index-handlers.test.js +184 -0
- package/dist/__tests__/tools/index-handlers.test.js.map +1 -0
- package/dist/__tests__/tools/instructions-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/instructions-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/instructions-handlers.test.js +53 -0
- package/dist/__tests__/tools/instructions-handlers.test.js.map +1 -0
- package/dist/__tests__/tools/memory-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/memory-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/memory-handlers.test.js +175 -0
- package/dist/__tests__/tools/memory-handlers.test.js.map +1 -0
- package/dist/__tests__/tools/search-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/search-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/search-handlers.test.js +229 -0
- package/dist/__tests__/tools/search-handlers.test.js.map +1 -0
- package/dist/__tests__/tools/symbol-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/symbol-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/symbol-handlers.test.js +348 -0
- package/dist/__tests__/tools/symbol-handlers.test.js.map +1 -0
- package/dist/__tests__/tools/worktree-handlers.test.d.ts +2 -0
- package/dist/__tests__/tools/worktree-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/tools/worktree-handlers.test.js +297 -0
- package/dist/__tests__/tools/worktree-handlers.test.js.map +1 -0
- package/dist/__tests__/utils/cache.test.d.ts +2 -0
- package/dist/__tests__/utils/cache.test.d.ts.map +1 -0
- package/dist/__tests__/utils/cache.test.js +147 -0
- package/dist/__tests__/utils/cache.test.js.map +1 -0
- package/dist/__tests__/utils/concurrency.test.d.ts +2 -0
- package/dist/__tests__/utils/concurrency.test.d.ts.map +1 -0
- package/dist/__tests__/utils/concurrency.test.js +83 -0
- package/dist/__tests__/utils/concurrency.test.js.map +1 -0
- package/dist/__tests__/utils/errors.test.d.ts +2 -0
- package/dist/__tests__/utils/errors.test.d.ts.map +1 -0
- package/dist/__tests__/utils/errors.test.js +136 -0
- package/dist/__tests__/utils/errors.test.js.map +1 -0
- package/dist/__tests__/utils/logger.test.d.ts +2 -0
- package/dist/__tests__/utils/logger.test.d.ts.map +1 -0
- package/dist/__tests__/utils/logger.test.js +131 -0
- package/dist/__tests__/utils/logger.test.js.map +1 -0
- package/dist/__tests__/utils/type-guards.test.d.ts +2 -0
- package/dist/__tests__/utils/type-guards.test.d.ts.map +1 -0
- package/dist/__tests__/utils/type-guards.test.js +80 -0
- package/dist/__tests__/utils/type-guards.test.js.map +1 -0
- package/dist/__tests__/worktree/worktree-manager.test.d.ts +2 -0
- package/dist/__tests__/worktree/worktree-manager.test.d.ts.map +1 -0
- package/dist/__tests__/worktree/worktree-manager.test.js +403 -0
- package/dist/__tests__/worktree/worktree-manager.test.js.map +1 -0
- package/dist/config.d.ts +191 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +788 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/beads.d.ts +35 -0
- package/dist/dashboard/beads.d.ts.map +1 -0
- package/dist/dashboard/beads.js +102 -0
- package/dist/dashboard/beads.js.map +1 -0
- package/dist/dashboard/events.d.ts +64 -0
- package/dist/dashboard/events.d.ts.map +1 -0
- package/dist/dashboard/events.js +211 -0
- package/dist/dashboard/events.js.map +1 -0
- package/dist/dashboard/index.d.ts +69 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +93 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/routes.d.ts +6 -0
- package/dist/dashboard/routes.d.ts.map +1 -0
- package/dist/dashboard/routes.js +505 -0
- package/dist/dashboard/routes.js.map +1 -0
- package/dist/dashboard/server.d.ts +27 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +72 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/dashboard/state.d.ts +172 -0
- package/dist/dashboard/state.d.ts.map +1 -0
- package/dist/dashboard/state.js +362 -0
- package/dist/dashboard/state.js.map +1 -0
- package/dist/dashboard/token-tracking.d.ts +143 -0
- package/dist/dashboard/token-tracking.d.ts.map +1 -0
- package/dist/dashboard/token-tracking.js +363 -0
- package/dist/dashboard/token-tracking.js.map +1 -0
- package/dist/dashboard/ui.d.ts +6 -0
- package/dist/dashboard/ui.d.ts.map +1 -0
- package/dist/dashboard/ui.js +2710 -0
- package/dist/dashboard/ui.js.map +1 -0
- package/dist/embeddings/gemini.d.ts +28 -0
- package/dist/embeddings/gemini.d.ts.map +1 -0
- package/dist/embeddings/gemini.js +165 -0
- package/dist/embeddings/gemini.js.map +1 -0
- package/dist/embeddings/index.d.ts +34 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +120 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/ollama.d.ts +22 -0
- package/dist/embeddings/ollama.d.ts.map +1 -0
- package/dist/embeddings/ollama.js +179 -0
- package/dist/embeddings/ollama.js.map +1 -0
- package/dist/embeddings/rate-limiter.d.ts +75 -0
- package/dist/embeddings/rate-limiter.d.ts.map +1 -0
- package/dist/embeddings/rate-limiter.js +145 -0
- package/dist/embeddings/rate-limiter.js.map +1 -0
- package/dist/embeddings/retry.d.ts +20 -0
- package/dist/embeddings/retry.d.ts.map +1 -0
- package/dist/embeddings/retry.js +227 -0
- package/dist/embeddings/retry.js.map +1 -0
- package/dist/embeddings/types.d.ts +103 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +23 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2028 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/index.d.ts +63 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +168 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/search/ast-chunker.d.ts +29 -0
- package/dist/search/ast-chunker.d.ts.map +1 -0
- package/dist/search/ast-chunker.js +236 -0
- package/dist/search/ast-chunker.js.map +1 -0
- package/dist/search/chunk-utils.d.ts +24 -0
- package/dist/search/chunk-utils.d.ts.map +1 -0
- package/dist/search/chunk-utils.js +41 -0
- package/dist/search/chunk-utils.js.map +1 -0
- package/dist/search/clustering.d.ts +77 -0
- package/dist/search/clustering.d.ts.map +1 -0
- package/dist/search/clustering.js +455 -0
- package/dist/search/clustering.js.map +1 -0
- package/dist/search/indexer.d.ts +377 -0
- package/dist/search/indexer.d.ts.map +1 -0
- package/dist/search/indexer.js +1557 -0
- package/dist/search/indexer.js.map +1 -0
- package/dist/search/tree-sitter-chunker.d.ts +64 -0
- package/dist/search/tree-sitter-chunker.d.ts.map +1 -0
- package/dist/search/tree-sitter-chunker.js +412 -0
- package/dist/search/tree-sitter-chunker.js.map +1 -0
- package/dist/symbols/index.d.ts +14 -0
- package/dist/symbols/index.d.ts.map +1 -0
- package/dist/symbols/index.js +19 -0
- package/dist/symbols/index.js.map +1 -0
- package/dist/symbols/name-path.d.ts +113 -0
- package/dist/symbols/name-path.d.ts.map +1 -0
- package/dist/symbols/name-path.js +194 -0
- package/dist/symbols/name-path.js.map +1 -0
- package/dist/symbols/pattern-search.d.ts +14 -0
- package/dist/symbols/pattern-search.d.ts.map +1 -0
- package/dist/symbols/pattern-search.js +224 -0
- package/dist/symbols/pattern-search.js.map +1 -0
- package/dist/symbols/reference-finder.d.ts +38 -0
- package/dist/symbols/reference-finder.d.ts.map +1 -0
- package/dist/symbols/reference-finder.js +376 -0
- package/dist/symbols/reference-finder.js.map +1 -0
- package/dist/symbols/symbol-editor.d.ts +81 -0
- package/dist/symbols/symbol-editor.d.ts.map +1 -0
- package/dist/symbols/symbol-editor.js +257 -0
- package/dist/symbols/symbol-editor.js.map +1 -0
- package/dist/symbols/symbol-extractor.d.ts +49 -0
- package/dist/symbols/symbol-extractor.d.ts.map +1 -0
- package/dist/symbols/symbol-extractor.js +593 -0
- package/dist/symbols/symbol-extractor.js.map +1 -0
- package/dist/symbols/symbol-renamer.d.ts +81 -0
- package/dist/symbols/symbol-renamer.d.ts.map +1 -0
- package/dist/symbols/symbol-renamer.js +204 -0
- package/dist/symbols/symbol-renamer.js.map +1 -0
- package/dist/symbols/types.d.ts +234 -0
- package/dist/symbols/types.d.ts.map +1 -0
- package/dist/symbols/types.js +106 -0
- package/dist/symbols/types.js.map +1 -0
- package/dist/tools/clustering-handlers.d.ts +70 -0
- package/dist/tools/clustering-handlers.d.ts.map +1 -0
- package/dist/tools/clustering-handlers.js +150 -0
- package/dist/tools/clustering-handlers.js.map +1 -0
- package/dist/tools/commit-handlers.d.ts +77 -0
- package/dist/tools/commit-handlers.d.ts.map +1 -0
- package/dist/tools/commit-handlers.js +251 -0
- package/dist/tools/commit-handlers.js.map +1 -0
- package/dist/tools/index-handlers.d.ts +31 -0
- package/dist/tools/index-handlers.d.ts.map +1 -0
- package/dist/tools/index-handlers.js +53 -0
- package/dist/tools/index-handlers.js.map +1 -0
- package/dist/tools/instructions-handlers.d.ts +25 -0
- package/dist/tools/instructions-handlers.d.ts.map +1 -0
- package/dist/tools/instructions-handlers.js +36 -0
- package/dist/tools/instructions-handlers.js.map +1 -0
- package/dist/tools/memory-handlers.d.ts +95 -0
- package/dist/tools/memory-handlers.d.ts.map +1 -0
- package/dist/tools/memory-handlers.js +126 -0
- package/dist/tools/memory-handlers.js.map +1 -0
- package/dist/tools/search-handlers.d.ts +51 -0
- package/dist/tools/search-handlers.d.ts.map +1 -0
- package/dist/tools/search-handlers.js +128 -0
- package/dist/tools/search-handlers.js.map +1 -0
- package/dist/tools/symbol-handlers.d.ts +171 -0
- package/dist/tools/symbol-handlers.d.ts.map +1 -0
- package/dist/tools/symbol-handlers.js +456 -0
- package/dist/tools/symbol-handlers.js.map +1 -0
- package/dist/tools/types.d.ts +32 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +17 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/worktree-handlers.d.ts +96 -0
- package/dist/tools/worktree-handlers.d.ts.map +1 -0
- package/dist/tools/worktree-handlers.js +186 -0
- package/dist/tools/worktree-handlers.js.map +1 -0
- package/dist/utils/cache.d.ts +77 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +134 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/concurrency.d.ts +32 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +57 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/errors.d.ts +36 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +91 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +37 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +114 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/type-guards.d.ts +17 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +25 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/worktree/index.d.ts +6 -0
- package/dist/worktree/index.d.ts.map +1 -0
- package/dist/worktree/index.js +6 -0
- package/dist/worktree/index.js.map +1 -0
- package/dist/worktree/types.d.ts +101 -0
- package/dist/worktree/types.d.ts.map +1 -0
- package/dist/worktree/types.js +6 -0
- package/dist/worktree/types.js.map +1 -0
- package/dist/worktree/worktree-manager.d.ts +80 -0
- package/dist/worktree/worktree-manager.d.ts.map +1 -0
- package/dist/worktree/worktree-manager.js +407 -0
- package/dist/worktree/worktree-manager.js.map +1 -0
- package/package.json +87 -0
- package/scripts/postinstall.js +48 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token bucket rate limiter for API requests
|
|
3
|
+
* Implements a classic token bucket algorithm with configurable rate and burst capacity
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Configuration options for the rate limiter
|
|
7
|
+
*/
|
|
8
|
+
export interface RateLimiterConfig {
|
|
9
|
+
/** Maximum requests per second (tokens added per second) */
|
|
10
|
+
requestsPerSecond: number;
|
|
11
|
+
/** Maximum burst capacity (bucket size) */
|
|
12
|
+
burstCapacity?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Default rate limiter configuration
|
|
16
|
+
* Conservative default suitable for most API rate limits
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_RATE_LIMITER_CONFIG: Required<RateLimiterConfig>;
|
|
19
|
+
/**
|
|
20
|
+
* Token bucket rate limiter
|
|
21
|
+
*
|
|
22
|
+
* The token bucket algorithm works as follows:
|
|
23
|
+
* - Tokens are added to the bucket at a fixed rate (requestsPerSecond)
|
|
24
|
+
* - Each request consumes one token
|
|
25
|
+
* - If no tokens are available, the request waits until one becomes available
|
|
26
|
+
* - The bucket has a maximum capacity (burstCapacity) to allow short bursts
|
|
27
|
+
*/
|
|
28
|
+
export declare class RateLimiter {
|
|
29
|
+
private tokens;
|
|
30
|
+
private lastRefillTime;
|
|
31
|
+
private readonly requestsPerSecond;
|
|
32
|
+
private readonly burstCapacity;
|
|
33
|
+
private pendingQueue;
|
|
34
|
+
private scheduledTimeout;
|
|
35
|
+
constructor(config?: RateLimiterConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Refill tokens based on elapsed time
|
|
38
|
+
*/
|
|
39
|
+
private refillTokens;
|
|
40
|
+
/**
|
|
41
|
+
* Calculate wait time until a token is available
|
|
42
|
+
*/
|
|
43
|
+
private getWaitTimeMs;
|
|
44
|
+
/**
|
|
45
|
+
* Schedule processing of the queue if not already scheduled
|
|
46
|
+
*/
|
|
47
|
+
private scheduleProcessing;
|
|
48
|
+
/**
|
|
49
|
+
* Process the pending queue
|
|
50
|
+
*/
|
|
51
|
+
private processQueue;
|
|
52
|
+
/**
|
|
53
|
+
* Acquire a token, waiting if necessary
|
|
54
|
+
* Returns a promise that resolves when a token is acquired
|
|
55
|
+
*/
|
|
56
|
+
acquire(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Try to acquire a token without waiting
|
|
59
|
+
* Returns true if a token was acquired, false otherwise
|
|
60
|
+
*/
|
|
61
|
+
tryAcquire(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Get the current number of available tokens
|
|
64
|
+
*/
|
|
65
|
+
getAvailableTokens(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Get the current queue length
|
|
68
|
+
*/
|
|
69
|
+
getQueueLength(): number;
|
|
70
|
+
/**
|
|
71
|
+
* Reset the rate limiter to initial state
|
|
72
|
+
*/
|
|
73
|
+
reset(): void;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/embeddings/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,iBAAiB,CAGnE,CAAC;AAEF;;;;;;;;GAQG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,gBAAgB,CAA8C;gBAE1D,MAAM,CAAC,EAAE,iBAAiB;IAQtC;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B;;;OAGG;IACH,UAAU,IAAI,OAAO;IAWrB;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAK5B;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,KAAK,IAAI,IAAI;CAcd"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token bucket rate limiter for API requests
|
|
3
|
+
* Implements a classic token bucket algorithm with configurable rate and burst capacity
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Default rate limiter configuration
|
|
7
|
+
* Conservative default suitable for most API rate limits
|
|
8
|
+
*/
|
|
9
|
+
export const DEFAULT_RATE_LIMITER_CONFIG = {
|
|
10
|
+
requestsPerSecond: 5,
|
|
11
|
+
burstCapacity: 10,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Token bucket rate limiter
|
|
15
|
+
*
|
|
16
|
+
* The token bucket algorithm works as follows:
|
|
17
|
+
* - Tokens are added to the bucket at a fixed rate (requestsPerSecond)
|
|
18
|
+
* - Each request consumes one token
|
|
19
|
+
* - If no tokens are available, the request waits until one becomes available
|
|
20
|
+
* - The bucket has a maximum capacity (burstCapacity) to allow short bursts
|
|
21
|
+
*/
|
|
22
|
+
export class RateLimiter {
|
|
23
|
+
tokens;
|
|
24
|
+
lastRefillTime;
|
|
25
|
+
requestsPerSecond;
|
|
26
|
+
burstCapacity;
|
|
27
|
+
pendingQueue = [];
|
|
28
|
+
scheduledTimeout = null;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
const opts = { ...DEFAULT_RATE_LIMITER_CONFIG, ...config };
|
|
31
|
+
this.requestsPerSecond = opts.requestsPerSecond;
|
|
32
|
+
this.burstCapacity = opts.burstCapacity;
|
|
33
|
+
this.tokens = this.burstCapacity; // Start with full bucket
|
|
34
|
+
this.lastRefillTime = Date.now();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Refill tokens based on elapsed time
|
|
38
|
+
*/
|
|
39
|
+
refillTokens() {
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
const elapsedSeconds = (now - this.lastRefillTime) / 1000;
|
|
42
|
+
const tokensToAdd = elapsedSeconds * this.requestsPerSecond;
|
|
43
|
+
this.tokens = Math.min(this.burstCapacity, this.tokens + tokensToAdd);
|
|
44
|
+
this.lastRefillTime = now;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Calculate wait time until a token is available
|
|
48
|
+
*/
|
|
49
|
+
getWaitTimeMs() {
|
|
50
|
+
if (this.tokens >= 1) {
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
// Calculate time until we have at least 1 token
|
|
54
|
+
const tokensNeeded = 1 - this.tokens;
|
|
55
|
+
const secondsToWait = tokensNeeded / this.requestsPerSecond;
|
|
56
|
+
return Math.ceil(secondsToWait * 1000);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Schedule processing of the queue if not already scheduled
|
|
60
|
+
*/
|
|
61
|
+
scheduleProcessing() {
|
|
62
|
+
if (this.scheduledTimeout !== null || this.pendingQueue.length === 0) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const waitTime = this.getWaitTimeMs();
|
|
66
|
+
this.scheduledTimeout = setTimeout(() => {
|
|
67
|
+
this.scheduledTimeout = null;
|
|
68
|
+
this.refillTokens();
|
|
69
|
+
this.processQueue();
|
|
70
|
+
// If there are still pending requests, schedule another processing
|
|
71
|
+
if (this.pendingQueue.length > 0) {
|
|
72
|
+
this.scheduleProcessing();
|
|
73
|
+
}
|
|
74
|
+
}, waitTime);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Process the pending queue
|
|
78
|
+
*/
|
|
79
|
+
processQueue() {
|
|
80
|
+
while (this.pendingQueue.length > 0 && this.tokens >= 1) {
|
|
81
|
+
this.tokens -= 1;
|
|
82
|
+
const resolve = this.pendingQueue.shift();
|
|
83
|
+
resolve();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Acquire a token, waiting if necessary
|
|
88
|
+
* Returns a promise that resolves when a token is acquired
|
|
89
|
+
*/
|
|
90
|
+
async acquire() {
|
|
91
|
+
this.refillTokens();
|
|
92
|
+
if (this.tokens >= 1) {
|
|
93
|
+
this.tokens -= 1;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Need to wait for a token
|
|
97
|
+
return new Promise((resolve) => {
|
|
98
|
+
this.pendingQueue.push(resolve);
|
|
99
|
+
this.scheduleProcessing();
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Try to acquire a token without waiting
|
|
104
|
+
* Returns true if a token was acquired, false otherwise
|
|
105
|
+
*/
|
|
106
|
+
tryAcquire() {
|
|
107
|
+
this.refillTokens();
|
|
108
|
+
if (this.tokens >= 1) {
|
|
109
|
+
this.tokens -= 1;
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get the current number of available tokens
|
|
116
|
+
*/
|
|
117
|
+
getAvailableTokens() {
|
|
118
|
+
this.refillTokens();
|
|
119
|
+
return Math.floor(this.tokens);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the current queue length
|
|
123
|
+
*/
|
|
124
|
+
getQueueLength() {
|
|
125
|
+
return this.pendingQueue.length;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Reset the rate limiter to initial state
|
|
129
|
+
*/
|
|
130
|
+
reset() {
|
|
131
|
+
this.tokens = this.burstCapacity;
|
|
132
|
+
this.lastRefillTime = Date.now();
|
|
133
|
+
// Clear any scheduled timeout
|
|
134
|
+
if (this.scheduledTimeout !== null) {
|
|
135
|
+
clearTimeout(this.scheduledTimeout);
|
|
136
|
+
this.scheduledTimeout = null;
|
|
137
|
+
}
|
|
138
|
+
// Clear pending queue
|
|
139
|
+
while (this.pendingQueue.length > 0) {
|
|
140
|
+
const resolve = this.pendingQueue.shift();
|
|
141
|
+
resolve();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/embeddings/rate-limiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry configuration options
|
|
3
|
+
*/
|
|
4
|
+
export interface RetryOptions {
|
|
5
|
+
maxRetries?: number;
|
|
6
|
+
baseDelayMs?: number;
|
|
7
|
+
maxDelayMs?: number;
|
|
8
|
+
maxResponseSizeBytes?: number;
|
|
9
|
+
/** Request timeout in milliseconds (default: 60000 = 60 seconds) */
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Set a callback function to receive retry log messages
|
|
14
|
+
*/
|
|
15
|
+
export declare function setRetryLogCallback(callback: ((level: 'info' | 'warn' | 'error', message: string) => void) | null): void;
|
|
16
|
+
/**
|
|
17
|
+
* Execute a fetch request with exponential backoff retry
|
|
18
|
+
*/
|
|
19
|
+
export declare function fetchWithRetry(url: string, options: RequestInit, retryOptions?: RetryOptions): Promise<Response>;
|
|
20
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/embeddings/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgCD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,GAC7E,IAAI,CAEN;AAsJD;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,WAAW,EACpB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,QAAQ,CAAC,CA8EnB"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default maximum response size (10MB)
|
|
3
|
+
*/
|
|
4
|
+
const DEFAULT_MAX_RESPONSE_SIZE = 10 * 1024 * 1024;
|
|
5
|
+
/**
|
|
6
|
+
* Default request timeout (60 seconds)
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_TIMEOUT_MS = 60000;
|
|
9
|
+
const DEFAULT_OPTIONS = {
|
|
10
|
+
maxRetries: 5,
|
|
11
|
+
baseDelayMs: 1000,
|
|
12
|
+
maxDelayMs: 60000,
|
|
13
|
+
maxResponseSizeBytes: DEFAULT_MAX_RESPONSE_SIZE,
|
|
14
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Sleep for a given number of milliseconds
|
|
18
|
+
*/
|
|
19
|
+
function sleep(ms) {
|
|
20
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Optional callback for logging retry attempts to external systems (e.g., dashboard)
|
|
24
|
+
*/
|
|
25
|
+
let retryLogCallback = null;
|
|
26
|
+
/**
|
|
27
|
+
* Set a callback function to receive retry log messages
|
|
28
|
+
*/
|
|
29
|
+
export function setRetryLogCallback(callback) {
|
|
30
|
+
retryLogCallback = callback;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Log a retry message to console and optional callback
|
|
34
|
+
*/
|
|
35
|
+
function logRetry(level, message) {
|
|
36
|
+
const prefixedMsg = `[glancey] ${message}`;
|
|
37
|
+
if (level === 'error') {
|
|
38
|
+
console.error(prefixedMsg);
|
|
39
|
+
}
|
|
40
|
+
else if (level === 'warn') {
|
|
41
|
+
console.warn(prefixedMsg);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.error(prefixedMsg); // Use stderr for all server logs
|
|
45
|
+
}
|
|
46
|
+
if (retryLogCallback) {
|
|
47
|
+
retryLogCallback(level, message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check if response size exceeds the maximum allowed
|
|
52
|
+
*/
|
|
53
|
+
function checkResponseSize(response, maxSize) {
|
|
54
|
+
const contentLength = response.headers?.get?.('content-length');
|
|
55
|
+
if (contentLength) {
|
|
56
|
+
const size = parseInt(contentLength, 10);
|
|
57
|
+
if (!isNaN(size) && size > maxSize) {
|
|
58
|
+
throw new Error(`Response size ${size} bytes exceeds maximum allowed ${maxSize} bytes`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check if an error is retryable (network errors, rate limits, server errors, timeouts)
|
|
64
|
+
*/
|
|
65
|
+
function isRetryableError(error) {
|
|
66
|
+
if (error instanceof Error) {
|
|
67
|
+
const message = error.message.toLowerCase();
|
|
68
|
+
// Retry on network errors and timeouts
|
|
69
|
+
if (message.includes('fetch') ||
|
|
70
|
+
message.includes('network') ||
|
|
71
|
+
message.includes('econnrefused') ||
|
|
72
|
+
message.includes('timeout') ||
|
|
73
|
+
message.includes('aborted')) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if a response status is retryable
|
|
81
|
+
*/
|
|
82
|
+
function isRetryableStatus(status) {
|
|
83
|
+
// Retry on rate limits (429), server errors (5xx), and some specific cases
|
|
84
|
+
return status === 429 || status === 408 || (status >= 500 && status < 600);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if a 429 error is a quota exhaustion (not retryable) vs temporary rate limit (retryable)
|
|
88
|
+
* Quota exhaustion means daily/monthly limits exceeded - retrying won't help
|
|
89
|
+
*/
|
|
90
|
+
async function isQuotaExhausted(response) {
|
|
91
|
+
if (response.status !== 429) {
|
|
92
|
+
return { exhausted: false, message: '' };
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const text = await response.text();
|
|
96
|
+
const lowerText = text.toLowerCase();
|
|
97
|
+
// Check for quota exhaustion indicators in the response
|
|
98
|
+
const quotaIndicators = [
|
|
99
|
+
'exceeded your current quota',
|
|
100
|
+
'resource_exhausted',
|
|
101
|
+
'quota exceeded',
|
|
102
|
+
'quotafailure',
|
|
103
|
+
'daily limit',
|
|
104
|
+
'monthly limit',
|
|
105
|
+
'billing',
|
|
106
|
+
];
|
|
107
|
+
for (const indicator of quotaIndicators) {
|
|
108
|
+
if (lowerText.includes(indicator)) {
|
|
109
|
+
return { exhausted: true, message: text };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { exhausted: false, message: text };
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// If we can't read the body, assume it's a temporary rate limit
|
|
116
|
+
return { exhausted: false, message: '' };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse Retry-After header value
|
|
121
|
+
* Returns delay in milliseconds, or null if not present/parseable
|
|
122
|
+
*/
|
|
123
|
+
function parseRetryAfter(response) {
|
|
124
|
+
const retryAfter = response.headers?.get?.('retry-after');
|
|
125
|
+
if (!retryAfter) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
// Try parsing as number of seconds
|
|
129
|
+
const seconds = parseInt(retryAfter, 10);
|
|
130
|
+
if (!isNaN(seconds) && seconds > 0) {
|
|
131
|
+
return seconds * 1000;
|
|
132
|
+
}
|
|
133
|
+
// Try parsing as HTTP date
|
|
134
|
+
const date = Date.parse(retryAfter);
|
|
135
|
+
if (!isNaN(date)) {
|
|
136
|
+
const delayMs = date - Date.now();
|
|
137
|
+
return delayMs > 0 ? delayMs : null;
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Calculate retry delay, respecting Retry-After header for 429 errors
|
|
143
|
+
*/
|
|
144
|
+
function calculateRetryDelay(response, attempt, opts) {
|
|
145
|
+
// For 429 errors, check Retry-After header first
|
|
146
|
+
if (response.status === 429) {
|
|
147
|
+
const retryAfter = parseRetryAfter(response);
|
|
148
|
+
if (retryAfter !== null) {
|
|
149
|
+
// Use Retry-After value, but cap at maxDelayMs and add small jitter
|
|
150
|
+
const jitter = Math.random() * 1000;
|
|
151
|
+
return Math.min(retryAfter + jitter, opts.maxDelayMs);
|
|
152
|
+
}
|
|
153
|
+
// No Retry-After header - use longer base delay for rate limits
|
|
154
|
+
const rateLimitBaseDelay = Math.max(opts.baseDelayMs * 2, 2000);
|
|
155
|
+
return Math.min(rateLimitBaseDelay * Math.pow(2, attempt), opts.maxDelayMs);
|
|
156
|
+
}
|
|
157
|
+
// Standard exponential backoff for other errors
|
|
158
|
+
return Math.min(opts.baseDelayMs * Math.pow(2, attempt), opts.maxDelayMs);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Execute a fetch request with exponential backoff retry
|
|
162
|
+
*/
|
|
163
|
+
export async function fetchWithRetry(url, options, retryOptions) {
|
|
164
|
+
const opts = { ...DEFAULT_OPTIONS, ...retryOptions };
|
|
165
|
+
let lastError = null;
|
|
166
|
+
for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
|
|
167
|
+
// Create AbortController for timeout
|
|
168
|
+
const controller = new AbortController();
|
|
169
|
+
const timeoutId = setTimeout(() => controller.abort(), opts.timeoutMs);
|
|
170
|
+
try {
|
|
171
|
+
const response = await fetch(url, {
|
|
172
|
+
...options,
|
|
173
|
+
signal: controller.signal,
|
|
174
|
+
});
|
|
175
|
+
clearTimeout(timeoutId);
|
|
176
|
+
// Check response size before processing
|
|
177
|
+
checkResponseSize(response, opts.maxResponseSizeBytes);
|
|
178
|
+
// If response is ok or non-retryable error, return it
|
|
179
|
+
if (response.ok || !isRetryableStatus(response.status)) {
|
|
180
|
+
return response;
|
|
181
|
+
}
|
|
182
|
+
// For 429 errors, check if it's quota exhaustion (not retryable)
|
|
183
|
+
if (response.status === 429) {
|
|
184
|
+
const { exhausted, message } = await isQuotaExhausted(response);
|
|
185
|
+
if (exhausted) {
|
|
186
|
+
logRetry('error', 'API quota exhausted (daily/monthly limit reached). Skipping retries.');
|
|
187
|
+
// Create a new Response with the same status but the body we already read
|
|
188
|
+
const errorResponse = new Response(message, {
|
|
189
|
+
status: response.status,
|
|
190
|
+
statusText: response.statusText,
|
|
191
|
+
headers: response.headers,
|
|
192
|
+
});
|
|
193
|
+
return errorResponse;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Retryable status code
|
|
197
|
+
if (attempt < opts.maxRetries) {
|
|
198
|
+
const delay = calculateRetryDelay(response, attempt, opts);
|
|
199
|
+
const retryAfterInfo = response.status === 429 ? ' (rate limited)' : '';
|
|
200
|
+
logRetry('warn', `Request failed with status ${response.status}${retryAfterInfo}, retrying in ${Math.round(delay / 1000)}s (attempt ${attempt + 1}/${opts.maxRetries})`);
|
|
201
|
+
await sleep(delay);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
// Last attempt, return the response even if it's an error
|
|
205
|
+
return response;
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
clearTimeout(timeoutId);
|
|
209
|
+
// Convert abort errors to timeout errors for clarity
|
|
210
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
211
|
+
lastError = new Error(`Request timeout after ${opts.timeoutMs}ms`);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
215
|
+
}
|
|
216
|
+
if (attempt < opts.maxRetries && isRetryableError(error)) {
|
|
217
|
+
const delay = Math.min(opts.baseDelayMs * Math.pow(2, attempt), opts.maxDelayMs);
|
|
218
|
+
logRetry('warn', `Request failed: ${lastError.message}, retrying in ${delay}ms (attempt ${attempt + 1}/${opts.maxRetries})`);
|
|
219
|
+
await sleep(delay);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
throw lastError;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
throw lastError || new Error('Request failed after retries');
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/embeddings/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding backend interface that all embedding providers must implement.
|
|
3
|
+
* Supports both single text and batch embedding operations.
|
|
4
|
+
*/
|
|
5
|
+
export interface EmbeddingBackend {
|
|
6
|
+
/** Display name of the embedding backend (e.g., 'gemini', 'ollama') */
|
|
7
|
+
name: string;
|
|
8
|
+
/**
|
|
9
|
+
* Initialize the backend, validating credentials and connectivity.
|
|
10
|
+
* @throws Error if initialization fails (e.g., invalid API key, server unreachable)
|
|
11
|
+
*/
|
|
12
|
+
initialize(): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Generate an embedding vector for a single text.
|
|
15
|
+
* @param text - The text to embed
|
|
16
|
+
* @returns A promise resolving to the embedding vector (array of numbers)
|
|
17
|
+
*/
|
|
18
|
+
embed(text: string): Promise<number[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Generate embedding vectors for multiple texts in a single batch.
|
|
21
|
+
* More efficient than calling embed() multiple times.
|
|
22
|
+
* @param texts - Array of texts to embed
|
|
23
|
+
* @returns A promise resolving to an array of embedding vectors
|
|
24
|
+
*/
|
|
25
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
26
|
+
/**
|
|
27
|
+
* Get the dimensionality of the embedding vectors produced by this backend.
|
|
28
|
+
* @returns The number of dimensions in the embedding vectors
|
|
29
|
+
*/
|
|
30
|
+
getDimensions(): number;
|
|
31
|
+
/**
|
|
32
|
+
* Get the model identifier used by this backend.
|
|
33
|
+
* @returns The model name/identifier (e.g., 'nomic-embed-text', 'gemini-embedding-001')
|
|
34
|
+
*/
|
|
35
|
+
getModel(): string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Configuration options for embedding backends.
|
|
39
|
+
*/
|
|
40
|
+
export interface EmbeddingConfig {
|
|
41
|
+
/** Which embedding backend to use */
|
|
42
|
+
backend: 'ollama' | 'gemini' | 'local';
|
|
43
|
+
/** Model name/identifier (backend-specific) */
|
|
44
|
+
model?: string;
|
|
45
|
+
/** API key for cloud-based backends (Gemini) */
|
|
46
|
+
apiKey?: string;
|
|
47
|
+
/** Base URL for the embedding API (useful for Ollama or custom endpoints) */
|
|
48
|
+
baseUrl?: string;
|
|
49
|
+
/** Rate limiting: maximum requests per second */
|
|
50
|
+
rateLimitRps?: number;
|
|
51
|
+
/** Rate limiting: maximum burst capacity (default: 10) */
|
|
52
|
+
rateLimitBurst?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Maximum number of texts to process in a single batch request.
|
|
55
|
+
* Large batches are automatically split into smaller chunks to prevent
|
|
56
|
+
* timeouts, memory issues, and API rate limit errors.
|
|
57
|
+
* Default: 100 for Ollama
|
|
58
|
+
*/
|
|
59
|
+
batchSize?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Maximum number of concurrent batch requests (Ollama only).
|
|
62
|
+
* Controls how many batch requests are sent in parallel.
|
|
63
|
+
* Default: 4 for Ollama
|
|
64
|
+
*/
|
|
65
|
+
concurrency?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Split an array into chunks of specified size.
|
|
69
|
+
* @param array - The array to chunk
|
|
70
|
+
* @param size - Maximum size of each chunk
|
|
71
|
+
* @returns Array of chunks
|
|
72
|
+
*/
|
|
73
|
+
export declare function chunkArray<T>(array: T[], size: number): T[][];
|
|
74
|
+
/**
|
|
75
|
+
* Default embedding configuration using Google Gemini.
|
|
76
|
+
* Gemini offers a free tier with 1500 RPM.
|
|
77
|
+
* Get API key at: https://aistudio.google.com/app/apikey
|
|
78
|
+
*/
|
|
79
|
+
export declare const DEFAULT_CONFIG: EmbeddingConfig;
|
|
80
|
+
/**
|
|
81
|
+
* Information about a backend fallback that occurred during initialization.
|
|
82
|
+
* This is returned when the configured backend fails and we fall back to another.
|
|
83
|
+
*/
|
|
84
|
+
export interface BackendFallbackInfo {
|
|
85
|
+
/** Whether a fallback occurred */
|
|
86
|
+
occurred: true;
|
|
87
|
+
/** The backend that was originally configured */
|
|
88
|
+
originalBackend: string;
|
|
89
|
+
/** The backend we fell back to */
|
|
90
|
+
fallbackBackend: string;
|
|
91
|
+
/** The error message from the original backend failure */
|
|
92
|
+
reason: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Result of creating an embedding backend, including optional fallback info.
|
|
96
|
+
*/
|
|
97
|
+
export interface CreateBackendResult {
|
|
98
|
+
/** The initialized embedding backend */
|
|
99
|
+
backend: EmbeddingBackend;
|
|
100
|
+
/** Information about fallback if one occurred */
|
|
101
|
+
fallback?: BackendFallbackInfo;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/embeddings/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEvC;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEjD;;;OAGG;IACH,aAAa,IAAI,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,IAAI,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEvC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAM7D;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,eAG5B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,kCAAkC;IAClC,QAAQ,EAAE,IAAI,CAAC;IACf,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iDAAiD;IACjD,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAChC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split an array into chunks of specified size.
|
|
3
|
+
* @param array - The array to chunk
|
|
4
|
+
* @param size - Maximum size of each chunk
|
|
5
|
+
* @returns Array of chunks
|
|
6
|
+
*/
|
|
7
|
+
export function chunkArray(array, size) {
|
|
8
|
+
const chunks = [];
|
|
9
|
+
for (let i = 0; i < array.length; i += size) {
|
|
10
|
+
chunks.push(array.slice(i, i + size));
|
|
11
|
+
}
|
|
12
|
+
return chunks;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Default embedding configuration using Google Gemini.
|
|
16
|
+
* Gemini offers a free tier with 1500 RPM.
|
|
17
|
+
* Get API key at: https://aistudio.google.com/app/apikey
|
|
18
|
+
*/
|
|
19
|
+
export const DEFAULT_CONFIG = {
|
|
20
|
+
backend: 'gemini',
|
|
21
|
+
model: 'gemini-embedding-001',
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/embeddings/types.ts"],"names":[],"mappings":"AAgFA;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAI,KAAU,EAAE,IAAY;IACpD,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,sBAAsB;CAC9B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Invalidate config and indexer caches to force reload on next access.
|
|
4
|
+
* Call this when config files change.
|
|
5
|
+
*/
|
|
6
|
+
export declare function invalidateCaches(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Reload config and reinitialize the indexer.
|
|
9
|
+
* Returns true if reload was successful, false otherwise.
|
|
10
|
+
*/
|
|
11
|
+
export declare function reloadConfig(): Promise<boolean>;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA8ZA;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CA0CrD"}
|