@defai.digital/ax-cli 3.5.2 → 3.6.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/.ax-cli/memory.json +8 -8
- package/README.md +27 -1
- package/dist/agent/chat-history-manager.d.ts +56 -0
- package/dist/agent/chat-history-manager.js +150 -0
- package/dist/agent/chat-history-manager.js.map +1 -0
- package/dist/agent/llm-agent.js +1 -1
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/agent/tool-manager.d.ts +39 -0
- package/dist/agent/tool-manager.js +76 -0
- package/dist/agent/tool-manager.js.map +1 -0
- package/dist/analyzers/ast/index.d.ts +9 -0
- package/dist/analyzers/ast/index.js +10 -0
- package/dist/analyzers/ast/index.js.map +1 -0
- package/dist/analyzers/ast/node-helpers.d.ts +81 -0
- package/dist/analyzers/ast/node-helpers.js +128 -0
- package/dist/analyzers/ast/node-helpers.js.map +1 -0
- package/dist/analyzers/ast/traverser.d.ts +67 -0
- package/dist/analyzers/ast/traverser.js +156 -0
- package/dist/analyzers/ast/traverser.js.map +1 -0
- package/dist/analyzers/best-practices/index.d.ts +10 -0
- package/dist/analyzers/best-practices/index.js +11 -0
- package/dist/analyzers/best-practices/index.js.map +1 -0
- package/dist/commands/setup.js +13 -5
- package/dist/commands/setup.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/client.d.ts +1 -0
- package/dist/llm/client.js +44 -0
- package/dist/llm/client.js.map +1 -1
- package/dist/mcp/ssrf-protection.d.ts +86 -0
- package/dist/mcp/ssrf-protection.js +313 -0
- package/dist/mcp/ssrf-protection.js.map +1 -0
- package/dist/mcp/validation.d.ts +4 -0
- package/dist/mcp/validation.js +122 -11
- package/dist/mcp/validation.js.map +1 -1
- package/dist/schemas/settings-schemas.d.ts +30 -0
- package/dist/schemas/settings-schemas.js +30 -0
- package/dist/schemas/settings-schemas.js.map +1 -1
- package/dist/tools/bash.d.ts +3 -2
- package/dist/tools/bash.js +31 -2
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/search.d.ts +1 -1
- package/dist/tools/search.js +121 -128
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/text-editor.js +52 -15
- package/dist/tools/text-editor.js.map +1 -1
- package/dist/ui/components/status-bar.js +2 -2
- package/dist/ui/components/status-bar.js.map +1 -1
- package/dist/ui/components/toast-notification.js +0 -1
- package/dist/ui/components/toast-notification.js.map +1 -1
- package/dist/utils/audit-logger.d.ts +247 -0
- package/dist/utils/audit-logger.js +374 -0
- package/dist/utils/audit-logger.js.map +1 -0
- package/dist/utils/command-security.d.ts +85 -0
- package/dist/utils/command-security.js +200 -0
- package/dist/utils/command-security.js.map +1 -0
- package/dist/utils/encryption.d.ts +78 -0
- package/dist/utils/encryption.js +216 -0
- package/dist/utils/encryption.js.map +1 -0
- package/dist/utils/error-sanitizer.d.ts +119 -0
- package/dist/utils/error-sanitizer.js +253 -0
- package/dist/utils/error-sanitizer.js.map +1 -0
- package/dist/utils/input-sanitizer.d.ts +210 -0
- package/dist/utils/input-sanitizer.js +362 -0
- package/dist/utils/input-sanitizer.js.map +1 -0
- package/dist/utils/json-utils.d.ts +13 -0
- package/dist/utils/json-utils.js +55 -1
- package/dist/utils/json-utils.js.map +1 -1
- package/dist/utils/parallel-analyzer.js +29 -12
- package/dist/utils/parallel-analyzer.js.map +1 -1
- package/dist/utils/path-security.d.ts +90 -0
- package/dist/utils/path-security.js +328 -0
- package/dist/utils/path-security.js.map +1 -0
- package/dist/utils/process-pool.d.ts +105 -0
- package/dist/utils/process-pool.js +326 -0
- package/dist/utils/process-pool.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +207 -0
- package/dist/utils/rate-limiter.js +303 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/settings-manager.js +83 -4
- package/dist/utils/settings-manager.js.map +1 -1
- package/eslint.config.js +3 -0
- package/package.json +1 -1
- package/.ax-cli/checkpoints/2025-11-20/checkpoint-11e9e0ba-c39d-4fd2-aa77-bc818811c921.json +0 -69
- package/.ax-cli/checkpoints/2025-11-20/checkpoint-2b260b98-b418-4c7c-9694-e2b94967e662.json +0 -24
- package/.ax-cli/checkpoints/2025-11-20/checkpoint-7e03601e-e8ab-4cd7-9841-a74b66adf78f.json +0 -69
- package/.ax-cli/checkpoints/2025-11-20/checkpoint-7f9c6562-771f-4fd0-adcf-9e7e9ac34ae8.json +0 -44
- package/.ax-cli/checkpoints/2025-11-20/checkpoint-e1ebe666-4c3a-4367-ba5c-27fe512a9c70.json +0 -24
- package/.ax-cli/checkpoints/2025-11-21/checkpoint-15743e7d-430c-4d76-b6fc-955d7a5c250c.json +0 -44
- package/.ax-cli/checkpoints/2025-11-21/checkpoint-25cf7679-0b3f-4988-83d7-704548fbba91.json +0 -69
- package/.ax-cli/checkpoints/2025-11-21/checkpoint-54aedbac-6db0-464e-8ebb-dbb3979e6dca.json +0 -24
- package/.ax-cli/checkpoints/2025-11-21/checkpoint-7658aed8-fe5d-4222-903f-1a7c63717ea7.json +0 -24
- package/.ax-cli/checkpoints/2025-11-21/checkpoint-c9c13497-40dc-4294-a327-6a5fc854eaa1.json +0 -69
- package/ax.config.json +0 -333
- package/dist/hooks/use-chat-reducer.d.ts +0 -61
- package/dist/hooks/use-chat-reducer.js +0 -118
- package/dist/hooks/use-chat-reducer.js.map +0 -1
- package/dist/hooks/use-enhanced-input.d.ts +0 -40
- package/dist/hooks/use-enhanced-input.js +0 -249
- package/dist/hooks/use-enhanced-input.js.map +0 -1
- package/dist/hooks/use-input-handler.d.ts +0 -46
- package/dist/hooks/use-input-handler.js +0 -1430
- package/dist/hooks/use-input-handler.js.map +0 -1
- package/dist/hooks/use-input-history.d.ts +0 -9
- package/dist/hooks/use-input-history.js +0 -112
- package/dist/hooks/use-input-history.js.map +0 -1
- package/dist/utils/paste-collapse.d.ts +0 -46
- package/dist/utils/paste-collapse.js +0 -77
- package/dist/utils/paste-collapse.js.map +0 -1
- package/packages/schemas/dist/index.d.ts +0 -14
- package/packages/schemas/dist/index.d.ts.map +0 -1
- package/packages/schemas/dist/index.js +0 -19
- package/packages/schemas/dist/index.js.map +0 -1
- package/packages/schemas/dist/public/core/brand-types.d.ts +0 -308
- package/packages/schemas/dist/public/core/brand-types.d.ts.map +0 -1
- package/packages/schemas/dist/public/core/brand-types.js +0 -243
- package/packages/schemas/dist/public/core/brand-types.js.map +0 -1
- package/packages/schemas/dist/public/core/enums.d.ts +0 -227
- package/packages/schemas/dist/public/core/enums.d.ts.map +0 -1
- package/packages/schemas/dist/public/core/enums.js +0 -222
- package/packages/schemas/dist/public/core/enums.js.map +0 -1
- package/packages/schemas/dist/public/core/id-types.d.ts +0 -286
- package/packages/schemas/dist/public/core/id-types.d.ts.map +0 -1
- package/packages/schemas/dist/public/core/id-types.js +0 -136
- package/packages/schemas/dist/public/core/id-types.js.map +0 -1
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Pool Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages a pool of reusable child processes to prevent memory leaks
|
|
5
|
+
* and resource exhaustion (REQ-ARCH-002).
|
|
6
|
+
*
|
|
7
|
+
* Key features:
|
|
8
|
+
* - Limits concurrent processes to prevent resource exhaustion
|
|
9
|
+
* - Queues requests when pool is full
|
|
10
|
+
* - Automatic cleanup of idle processes
|
|
11
|
+
* - Graceful shutdown with proper cleanup
|
|
12
|
+
* - Memory leak prevention through proper event listener management
|
|
13
|
+
*
|
|
14
|
+
* @module process-pool
|
|
15
|
+
*/
|
|
16
|
+
import { spawn } from 'child_process';
|
|
17
|
+
import { EventEmitter } from 'events';
|
|
18
|
+
/**
|
|
19
|
+
* Process pool manager for efficient process reuse
|
|
20
|
+
*/
|
|
21
|
+
export class ProcessPool extends EventEmitter {
|
|
22
|
+
maxProcesses;
|
|
23
|
+
processTimeout;
|
|
24
|
+
maxQueueSize;
|
|
25
|
+
activeProcesses = new Set();
|
|
26
|
+
taskQueue = [];
|
|
27
|
+
shuttingDown = false;
|
|
28
|
+
idleTimers = new Map();
|
|
29
|
+
constructor(config = {}) {
|
|
30
|
+
super();
|
|
31
|
+
this.maxProcesses = config.maxProcesses ?? 5;
|
|
32
|
+
this.processTimeout = config.processTimeout ?? 30000;
|
|
33
|
+
this.maxQueueSize = config.maxQueueSize ?? 100;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Execute a command using the process pool
|
|
37
|
+
*/
|
|
38
|
+
async execute(options) {
|
|
39
|
+
if (this.shuttingDown) {
|
|
40
|
+
throw new Error('Process pool is shutting down');
|
|
41
|
+
}
|
|
42
|
+
// Check queue size limit
|
|
43
|
+
if (this.taskQueue.length >= this.maxQueueSize) {
|
|
44
|
+
throw new Error(`Process pool queue is full (max: ${this.maxQueueSize})`);
|
|
45
|
+
}
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const task = {
|
|
48
|
+
options,
|
|
49
|
+
resolve,
|
|
50
|
+
reject,
|
|
51
|
+
timestamp: Date.now(),
|
|
52
|
+
};
|
|
53
|
+
this.taskQueue.push(task);
|
|
54
|
+
this.processQueue();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Process the task queue
|
|
59
|
+
*/
|
|
60
|
+
processQueue() {
|
|
61
|
+
// Don't process if shutting down
|
|
62
|
+
if (this.shuttingDown) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Process tasks while we have capacity
|
|
66
|
+
while (this.taskQueue.length > 0 &&
|
|
67
|
+
this.activeProcesses.size < this.maxProcesses) {
|
|
68
|
+
const task = this.taskQueue.shift();
|
|
69
|
+
if (!task)
|
|
70
|
+
break;
|
|
71
|
+
this.executeTask(task);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Execute a single task
|
|
76
|
+
*/
|
|
77
|
+
async executeTask(task) {
|
|
78
|
+
const { options, resolve, reject } = task;
|
|
79
|
+
try {
|
|
80
|
+
const result = await this.spawnProcess(options);
|
|
81
|
+
resolve(result);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
// Process next task in queue
|
|
88
|
+
this.processQueue();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Spawn a process and manage its lifecycle
|
|
93
|
+
*/
|
|
94
|
+
async spawnProcess(options) {
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
const proc = spawn(options.command, options.args, {
|
|
97
|
+
cwd: options.cwd,
|
|
98
|
+
});
|
|
99
|
+
this.activeProcesses.add(proc);
|
|
100
|
+
let stdout = '';
|
|
101
|
+
let stderr = '';
|
|
102
|
+
let isResolved = false;
|
|
103
|
+
let timeoutHandle = null;
|
|
104
|
+
// Set timeout
|
|
105
|
+
const timeout = options.timeout ?? this.processTimeout;
|
|
106
|
+
if (timeout > 0) {
|
|
107
|
+
timeoutHandle = setTimeout(() => {
|
|
108
|
+
if (!isResolved) {
|
|
109
|
+
isResolved = true;
|
|
110
|
+
this.cleanupProcess(proc, timeoutHandle);
|
|
111
|
+
reject(new Error(`Process timeout after ${timeout}ms`));
|
|
112
|
+
}
|
|
113
|
+
}, timeout);
|
|
114
|
+
}
|
|
115
|
+
// Collect stdout
|
|
116
|
+
if (proc.stdout) {
|
|
117
|
+
proc.stdout.on('data', (data) => {
|
|
118
|
+
stdout += data.toString();
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
// Collect stderr
|
|
122
|
+
if (proc.stderr) {
|
|
123
|
+
proc.stderr.on('data', (data) => {
|
|
124
|
+
stderr += data.toString();
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// Handle process exit
|
|
128
|
+
proc.on('close', (code, signal) => {
|
|
129
|
+
if (isResolved) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
isResolved = true;
|
|
133
|
+
this.cleanupProcess(proc, timeoutHandle);
|
|
134
|
+
resolve({
|
|
135
|
+
stdout,
|
|
136
|
+
stderr,
|
|
137
|
+
exitCode: code,
|
|
138
|
+
signal: signal,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
// Handle process errors
|
|
142
|
+
proc.on('error', (error) => {
|
|
143
|
+
if (isResolved) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
isResolved = true;
|
|
147
|
+
this.cleanupProcess(proc, timeoutHandle);
|
|
148
|
+
reject(error);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Cleanup process and associated resources
|
|
154
|
+
*/
|
|
155
|
+
cleanupProcess(proc, timeoutHandle) {
|
|
156
|
+
// Clear timeout
|
|
157
|
+
if (timeoutHandle) {
|
|
158
|
+
clearTimeout(timeoutHandle);
|
|
159
|
+
}
|
|
160
|
+
// Clear idle timer if exists
|
|
161
|
+
const idleTimer = this.idleTimers.get(proc);
|
|
162
|
+
if (idleTimer) {
|
|
163
|
+
clearTimeout(idleTimer);
|
|
164
|
+
this.idleTimers.delete(proc);
|
|
165
|
+
}
|
|
166
|
+
// Remove all event listeners to prevent memory leaks
|
|
167
|
+
if (proc.stdout) {
|
|
168
|
+
proc.stdout.removeAllListeners();
|
|
169
|
+
}
|
|
170
|
+
if (proc.stderr) {
|
|
171
|
+
proc.stderr.removeAllListeners();
|
|
172
|
+
}
|
|
173
|
+
proc.removeAllListeners();
|
|
174
|
+
// Kill process if still running
|
|
175
|
+
if (proc.exitCode === null && proc.signalCode === null) {
|
|
176
|
+
try {
|
|
177
|
+
proc.kill('SIGTERM');
|
|
178
|
+
// Force kill after 3 seconds if SIGTERM doesn't work
|
|
179
|
+
const forceKillTimeout = setTimeout(() => {
|
|
180
|
+
try {
|
|
181
|
+
if (proc.exitCode === null && !proc.killed) {
|
|
182
|
+
proc.kill('SIGKILL');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// Process already terminated
|
|
187
|
+
}
|
|
188
|
+
// Always clear timeout to prevent leak
|
|
189
|
+
clearTimeout(forceKillTimeout);
|
|
190
|
+
}, 3000);
|
|
191
|
+
// Clear force kill timeout when process exits
|
|
192
|
+
// NOTE: Use setImmediate to ensure listener fires even if already exited
|
|
193
|
+
setImmediate(() => {
|
|
194
|
+
if (proc.exitCode !== null || proc.signalCode !== null) {
|
|
195
|
+
clearTimeout(forceKillTimeout);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
proc.once('exit', () => clearTimeout(forceKillTimeout));
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// Process already terminated or can't be killed
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Remove from active set
|
|
207
|
+
this.activeProcesses.delete(proc);
|
|
208
|
+
// Emit metrics event
|
|
209
|
+
this.emit('processCompleted', {
|
|
210
|
+
activeProcesses: this.activeProcesses.size,
|
|
211
|
+
queuedTasks: this.taskQueue.length,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get pool statistics
|
|
216
|
+
*/
|
|
217
|
+
getStats() {
|
|
218
|
+
return {
|
|
219
|
+
activeProcesses: this.activeProcesses.size,
|
|
220
|
+
queuedTasks: this.taskQueue.length,
|
|
221
|
+
maxProcesses: this.maxProcesses,
|
|
222
|
+
maxQueueSize: this.maxQueueSize,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Shutdown the pool gracefully
|
|
227
|
+
*/
|
|
228
|
+
async shutdown(force = false) {
|
|
229
|
+
this.shuttingDown = true;
|
|
230
|
+
// Reject all queued tasks
|
|
231
|
+
while (this.taskQueue.length > 0) {
|
|
232
|
+
const task = this.taskQueue.shift();
|
|
233
|
+
if (task) {
|
|
234
|
+
task.reject(new Error('Process pool shutting down'));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Wait for active processes to complete or force kill
|
|
238
|
+
if (force) {
|
|
239
|
+
// Force kill all active processes
|
|
240
|
+
for (const proc of this.activeProcesses) {
|
|
241
|
+
try {
|
|
242
|
+
proc.kill('SIGKILL');
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// Ignore errors
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
this.activeProcesses.clear();
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
// Wait for active processes to complete (with timeout)
|
|
252
|
+
const shutdownTimeout = 10000; // 10 seconds
|
|
253
|
+
const startTime = Date.now();
|
|
254
|
+
while (this.activeProcesses.size > 0) {
|
|
255
|
+
if (Date.now() - startTime > shutdownTimeout) {
|
|
256
|
+
// Force kill remaining processes
|
|
257
|
+
for (const proc of this.activeProcesses) {
|
|
258
|
+
try {
|
|
259
|
+
proc.kill('SIGKILL');
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// Ignore errors
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
this.activeProcesses.clear();
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
// Wait 100ms before checking again
|
|
269
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Clear all idle timers
|
|
273
|
+
for (const timer of this.idleTimers.values()) {
|
|
274
|
+
clearTimeout(timer);
|
|
275
|
+
}
|
|
276
|
+
this.idleTimers.clear();
|
|
277
|
+
this.emit('shutdown');
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Check if pool is idle (no active processes or queued tasks)
|
|
281
|
+
*/
|
|
282
|
+
isIdle() {
|
|
283
|
+
return this.activeProcesses.size === 0 && this.taskQueue.length === 0;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Check if pool is at capacity
|
|
287
|
+
*/
|
|
288
|
+
isAtCapacity() {
|
|
289
|
+
return this.activeProcesses.size >= this.maxProcesses;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Singleton process pool instance for ripgrep
|
|
294
|
+
*/
|
|
295
|
+
let ripgrepPool = null;
|
|
296
|
+
/**
|
|
297
|
+
* Get or create the ripgrep process pool
|
|
298
|
+
*/
|
|
299
|
+
export function getRipgrepPool() {
|
|
300
|
+
if (!ripgrepPool) {
|
|
301
|
+
ripgrepPool = new ProcessPool({
|
|
302
|
+
maxProcesses: 5,
|
|
303
|
+
processTimeout: 30000,
|
|
304
|
+
maxQueueSize: 100,
|
|
305
|
+
});
|
|
306
|
+
// Cleanup on process exit
|
|
307
|
+
process.on('beforeExit', () => {
|
|
308
|
+
if (ripgrepPool) {
|
|
309
|
+
ripgrepPool.shutdown(true).catch(() => {
|
|
310
|
+
// Ignore errors during shutdown
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
return ripgrepPool;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Shutdown the ripgrep pool (for testing)
|
|
319
|
+
*/
|
|
320
|
+
export async function shutdownRipgrepPool() {
|
|
321
|
+
if (ripgrepPool) {
|
|
322
|
+
await ripgrepPool.shutdown();
|
|
323
|
+
ripgrepPool = null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=process-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-pool.js","sourceRoot":"","sources":["../../src/utils/process-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limiting Utilities (REQ-SEC-006)
|
|
3
|
+
*
|
|
4
|
+
* Implements token bucket algorithm for rate limiting API calls and user actions
|
|
5
|
+
* Prevents API abuse and ensures fair resource usage
|
|
6
|
+
*
|
|
7
|
+
* Security: Protects against:
|
|
8
|
+
* - API abuse (excessive requests)
|
|
9
|
+
* - Resource exhaustion
|
|
10
|
+
* - Denial of service (unintentional)
|
|
11
|
+
*/
|
|
12
|
+
export interface RateLimitConfig {
|
|
13
|
+
/**
|
|
14
|
+
* Maximum number of requests allowed in the window
|
|
15
|
+
*/
|
|
16
|
+
maxRequests: number;
|
|
17
|
+
/**
|
|
18
|
+
* Time window in milliseconds
|
|
19
|
+
*/
|
|
20
|
+
windowMs: number;
|
|
21
|
+
/**
|
|
22
|
+
* Optional: burst allowance (can exceed limit briefly)
|
|
23
|
+
*/
|
|
24
|
+
burstAllowance?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface RateLimitResult {
|
|
27
|
+
/**
|
|
28
|
+
* Whether the request is allowed
|
|
29
|
+
*/
|
|
30
|
+
allowed: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Tokens remaining in the current window
|
|
33
|
+
*/
|
|
34
|
+
remaining: number;
|
|
35
|
+
/**
|
|
36
|
+
* Time until the rate limit resets (in milliseconds)
|
|
37
|
+
*/
|
|
38
|
+
resetIn: number;
|
|
39
|
+
/**
|
|
40
|
+
* Total limit for this rate limiter
|
|
41
|
+
*/
|
|
42
|
+
limit: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Token Bucket Rate Limiter
|
|
46
|
+
*
|
|
47
|
+
* Uses the token bucket algorithm which allows bursts while maintaining
|
|
48
|
+
* a steady average rate. Tokens are added at a constant rate, and requests
|
|
49
|
+
* consume tokens.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const limiter = new RateLimiter({
|
|
54
|
+
* maxRequests: 60,
|
|
55
|
+
* windowMs: 60000, // 60 requests per minute
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const result = limiter.tryAcquire();
|
|
59
|
+
* if (result.allowed) {
|
|
60
|
+
* // Make API call
|
|
61
|
+
* } else {
|
|
62
|
+
* console.log(`Rate limit exceeded. Try again in ${result.resetIn}ms`);
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare class RateLimiter {
|
|
67
|
+
private tokens;
|
|
68
|
+
private readonly maxTokens;
|
|
69
|
+
private readonly refillRate;
|
|
70
|
+
private lastRefill;
|
|
71
|
+
private readonly config;
|
|
72
|
+
constructor(config: RateLimitConfig);
|
|
73
|
+
/**
|
|
74
|
+
* Refill tokens based on elapsed time
|
|
75
|
+
*/
|
|
76
|
+
private refill;
|
|
77
|
+
/**
|
|
78
|
+
* Try to acquire a token (allow a request)
|
|
79
|
+
*
|
|
80
|
+
* @param cost - Number of tokens to consume (default: 1)
|
|
81
|
+
* @returns Rate limit result indicating if request is allowed
|
|
82
|
+
*/
|
|
83
|
+
tryAcquire(cost?: number): RateLimitResult;
|
|
84
|
+
/**
|
|
85
|
+
* Get current state without consuming a token
|
|
86
|
+
*/
|
|
87
|
+
getState(): RateLimitResult;
|
|
88
|
+
/**
|
|
89
|
+
* Reset the rate limiter (clear all tokens)
|
|
90
|
+
*/
|
|
91
|
+
reset(): void;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Multi-tier Rate Limiter
|
|
95
|
+
*
|
|
96
|
+
* Enforces multiple rate limits simultaneously (e.g., per-second, per-minute, per-hour)
|
|
97
|
+
* Request is only allowed if ALL tiers allow it
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const limiter = new MultiTierRateLimiter([
|
|
102
|
+
* { maxRequests: 10, windowMs: 1000 }, // 10/second
|
|
103
|
+
* { maxRequests: 100, windowMs: 60000 }, // 100/minute
|
|
104
|
+
* ]);
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare class MultiTierRateLimiter {
|
|
108
|
+
private limiters;
|
|
109
|
+
constructor(configs: RateLimitConfig[]);
|
|
110
|
+
/**
|
|
111
|
+
* Try to acquire across all tiers
|
|
112
|
+
* Request is only allowed if ALL tiers allow it
|
|
113
|
+
*/
|
|
114
|
+
tryAcquire(cost?: number): RateLimitResult;
|
|
115
|
+
/**
|
|
116
|
+
* Get current state (most restrictive tier)
|
|
117
|
+
*/
|
|
118
|
+
getState(): RateLimitResult;
|
|
119
|
+
/**
|
|
120
|
+
* Reset all tiers
|
|
121
|
+
*/
|
|
122
|
+
reset(): void;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Keyed Rate Limiter
|
|
126
|
+
*
|
|
127
|
+
* Maintains separate rate limits for different keys (e.g., per-user, per-IP)
|
|
128
|
+
* Automatically cleans up old entries to prevent memory leaks
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const limiter = new KeyedRateLimiter({
|
|
133
|
+
* maxRequests: 100,
|
|
134
|
+
* windowMs: 60000,
|
|
135
|
+
* });
|
|
136
|
+
*
|
|
137
|
+
* // Different limits for different users
|
|
138
|
+
* const result = limiter.tryAcquire('user-123');
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare class KeyedRateLimiter {
|
|
142
|
+
private limiters;
|
|
143
|
+
private readonly config;
|
|
144
|
+
private cleanupTimer;
|
|
145
|
+
private readonly maxKeys;
|
|
146
|
+
constructor(config: RateLimitConfig, maxKeys?: number);
|
|
147
|
+
/**
|
|
148
|
+
* Get or create a rate limiter for the given key
|
|
149
|
+
*/
|
|
150
|
+
private getLimiter;
|
|
151
|
+
/**
|
|
152
|
+
* Try to acquire for a specific key
|
|
153
|
+
*/
|
|
154
|
+
tryAcquire(key: string, cost?: number): RateLimitResult;
|
|
155
|
+
/**
|
|
156
|
+
* Get state for a specific key
|
|
157
|
+
*/
|
|
158
|
+
getState(key: string): RateLimitResult;
|
|
159
|
+
/**
|
|
160
|
+
* Reset a specific key
|
|
161
|
+
*/
|
|
162
|
+
reset(key: string): void;
|
|
163
|
+
/**
|
|
164
|
+
* Clean up inactive limiters
|
|
165
|
+
*/
|
|
166
|
+
private cleanup;
|
|
167
|
+
/**
|
|
168
|
+
* Dispose of resources
|
|
169
|
+
*/
|
|
170
|
+
dispose(): void;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Default rate limit configurations for common use cases
|
|
174
|
+
*/
|
|
175
|
+
export declare const DEFAULT_RATE_LIMITS: {
|
|
176
|
+
/**
|
|
177
|
+
* API calls - 60 requests per minute
|
|
178
|
+
*/
|
|
179
|
+
readonly API: {
|
|
180
|
+
readonly maxRequests: 60;
|
|
181
|
+
readonly windowMs: number;
|
|
182
|
+
readonly burstAllowance: 10;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* LLM API calls - 20 requests per minute (more expensive)
|
|
186
|
+
*/
|
|
187
|
+
readonly LLM_API: {
|
|
188
|
+
readonly maxRequests: 20;
|
|
189
|
+
readonly windowMs: number;
|
|
190
|
+
readonly burstAllowance: 5;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* User actions - 100 requests per minute
|
|
194
|
+
*/
|
|
195
|
+
readonly USER_ACTIONS: {
|
|
196
|
+
readonly maxRequests: 100;
|
|
197
|
+
readonly windowMs: number;
|
|
198
|
+
readonly burstAllowance: 20;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* File operations - 50 per minute
|
|
202
|
+
*/
|
|
203
|
+
readonly FILE_OPS: {
|
|
204
|
+
readonly maxRequests: 50;
|
|
205
|
+
readonly windowMs: number;
|
|
206
|
+
};
|
|
207
|
+
};
|