agentic-flow 1.10.0 → 1.10.1

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.
Files changed (33) hide show
  1. package/dist/utils/adaptive-pool-sizing.js +414 -0
  2. package/dist/utils/circular-rate-limiter.js +391 -0
  3. package/dist/utils/dynamic-compression.js +298 -0
  4. package/dist/utils/http2-multiplexing.js +319 -0
  5. package/dist/utils/lazy-auth.js +311 -0
  6. package/dist/utils/server-push.js +251 -0
  7. package/dist/utils/zero-copy-buffer.js +286 -0
  8. package/docs/DOCKER-VERIFICATION.md +207 -0
  9. package/docs/ISSUE-55-VALIDATION.md +25 -6
  10. package/docs/NPX_AGENTDB_SETUP.md +175 -0
  11. package/docs/PHASE2-IMPLEMENTATION-SUMMARY.md +275 -0
  12. package/docs/PHASE2-PHASE3-COMPLETE-SUMMARY.md +453 -0
  13. package/docs/PHASE3-IMPLEMENTATION-SUMMARY.md +357 -0
  14. package/docs/PUBLISH_GUIDE.md +438 -0
  15. package/docs/RELEASE-v1.10.0-COMPLETE.md +382 -0
  16. package/docs/archive/.agentdb-instructions.md +66 -0
  17. package/docs/archive/AGENT-BOOSTER-STATUS.md +292 -0
  18. package/docs/archive/CHANGELOG-v1.3.0.md +120 -0
  19. package/docs/archive/COMPLETION_REPORT_v1.7.1.md +335 -0
  20. package/docs/archive/IMPLEMENTATION_SUMMARY_v1.7.1.md +241 -0
  21. package/docs/archive/SUPABASE-INTEGRATION-COMPLETE.md +357 -0
  22. package/docs/archive/TESTING_QUICK_START.md +223 -0
  23. package/docs/archive/TOOL-EMULATION-INTEGRATION-ISSUE.md +669 -0
  24. package/docs/archive/VALIDATION_v1.7.1.md +234 -0
  25. package/docs/releases/PUBLISH_CHECKLIST_v1.10.0.md +396 -0
  26. package/docs/releases/PUBLISH_SUMMARY_v1.7.1.md +198 -0
  27. package/docs/releases/RELEASE_NOTES_v1.10.0.md +464 -0
  28. package/docs/releases/RELEASE_NOTES_v1.7.0.md +297 -0
  29. package/docs/releases/RELEASE_v1.7.1.md +327 -0
  30. package/package.json +1 -1
  31. package/validation/docker-npm-validation.sh +170 -0
  32. package/validation/simple-npm-validation.sh +131 -0
  33. package/validation/test-gemini-models.ts +200 -0
@@ -0,0 +1,319 @@
1
+ /**
2
+ * HTTP/2 Multiplexing Optimization
3
+ * Stream prioritization and flow control for concurrent request optimization
4
+ * Phase 2 Optimization
5
+ */
6
+ /**
7
+ * HTTP/2 Multiplexing Manager
8
+ * Manages stream prioritization and concurrent request handling
9
+ */
10
+ export class HTTP2MultiplexingManager {
11
+ config;
12
+ activeStreams = new Map();
13
+ priorityQueues = new Map();
14
+ stats;
15
+ constructor(config) {
16
+ this.config = {
17
+ enabled: config.enabled,
18
+ maxConcurrentStreams: config.maxConcurrentStreams || 100,
19
+ defaultPriority: config.defaultPriority || 16,
20
+ enableFlowControl: config.enableFlowControl !== false,
21
+ initialWindowSize: config.initialWindowSize || 65535
22
+ };
23
+ this.stats = {
24
+ totalStreams: 0,
25
+ activeStreams: 0,
26
+ completedStreams: 0,
27
+ averageDuration: 0,
28
+ priorityChanges: 0
29
+ };
30
+ this.initializePriorityQueues();
31
+ }
32
+ /**
33
+ * Initialize priority queues (1-256)
34
+ */
35
+ initializePriorityQueues() {
36
+ for (let i = 1; i <= 256; i++) {
37
+ this.priorityQueues.set(i, new Set());
38
+ }
39
+ }
40
+ /**
41
+ * Register a new stream
42
+ */
43
+ registerStream(stream, priority) {
44
+ if (!this.config.enabled)
45
+ return;
46
+ const streamId = stream.id || 0;
47
+ const streamPriority = priority?.weight || this.config.defaultPriority;
48
+ const info = {
49
+ stream,
50
+ priority: streamPriority,
51
+ bytesReceived: 0,
52
+ bytesSent: 0,
53
+ startTime: Date.now(),
54
+ state: 'open'
55
+ };
56
+ this.activeStreams.set(streamId, info);
57
+ this.priorityQueues.get(streamPriority)?.add(streamId);
58
+ this.stats.totalStreams++;
59
+ this.stats.activeStreams++;
60
+ // Set stream priority
61
+ if (priority) {
62
+ this.setPriority(stream, priority);
63
+ }
64
+ // Setup event handlers
65
+ this.setupStreamHandlers(stream, streamId);
66
+ }
67
+ /**
68
+ * Set stream priority
69
+ */
70
+ setPriority(stream, priority) {
71
+ try {
72
+ stream.priority(priority);
73
+ const streamId = stream.id || 0;
74
+ const info = this.activeStreams.get(streamId);
75
+ if (info) {
76
+ // Move to new priority queue
77
+ const oldPriority = info.priority;
78
+ const newPriority = priority.weight;
79
+ this.priorityQueues.get(oldPriority)?.delete(streamId);
80
+ info.priority = newPriority;
81
+ this.priorityQueues.get(newPriority)?.add(streamId);
82
+ this.stats.priorityChanges++;
83
+ }
84
+ }
85
+ catch (error) {
86
+ // Stream may be closed
87
+ }
88
+ }
89
+ /**
90
+ * Adjust stream priority based on load
91
+ */
92
+ adjustPriority(streamId, adjustment) {
93
+ const info = this.activeStreams.get(streamId);
94
+ if (!info)
95
+ return;
96
+ const newPriority = Math.max(1, Math.min(256, info.priority + adjustment));
97
+ this.setPriority(info.stream, {
98
+ weight: newPriority,
99
+ exclusive: false
100
+ });
101
+ }
102
+ /**
103
+ * Get next stream to process based on priority
104
+ */
105
+ getNextStream() {
106
+ // Process highest priority streams first (256 is highest)
107
+ for (let priority = 256; priority >= 1; priority--) {
108
+ const queue = this.priorityQueues.get(priority);
109
+ if (queue && queue.size > 0) {
110
+ const streamId = queue.values().next().value;
111
+ if (streamId !== undefined) {
112
+ const info = this.activeStreams.get(streamId);
113
+ if (info && info.state === 'open') {
114
+ return info.stream;
115
+ }
116
+ }
117
+ }
118
+ }
119
+ return null;
120
+ }
121
+ /**
122
+ * Setup stream event handlers
123
+ */
124
+ setupStreamHandlers(stream, streamId) {
125
+ stream.on('data', (chunk) => {
126
+ const info = this.activeStreams.get(streamId);
127
+ if (info) {
128
+ info.bytesReceived += chunk.length;
129
+ }
130
+ });
131
+ stream.on('end', () => {
132
+ this.updateStreamState(streamId, 'half-closed');
133
+ });
134
+ stream.on('close', () => {
135
+ this.handleStreamClose(streamId);
136
+ });
137
+ stream.on('error', () => {
138
+ this.handleStreamClose(streamId);
139
+ });
140
+ }
141
+ /**
142
+ * Update stream state
143
+ */
144
+ updateStreamState(streamId, state) {
145
+ const info = this.activeStreams.get(streamId);
146
+ if (info) {
147
+ info.state = state;
148
+ }
149
+ }
150
+ /**
151
+ * Handle stream closure
152
+ */
153
+ handleStreamClose(streamId) {
154
+ const info = this.activeStreams.get(streamId);
155
+ if (!info)
156
+ return;
157
+ // Remove from priority queue
158
+ this.priorityQueues.get(info.priority)?.delete(streamId);
159
+ // Update statistics
160
+ const duration = Date.now() - info.startTime;
161
+ this.updateStats(duration);
162
+ // Remove from active streams
163
+ this.activeStreams.delete(streamId);
164
+ this.stats.activeStreams--;
165
+ this.stats.completedStreams++;
166
+ }
167
+ /**
168
+ * Update statistics
169
+ */
170
+ updateStats(duration) {
171
+ const currentAvg = this.stats.averageDuration;
172
+ const total = this.stats.completedStreams;
173
+ this.stats.averageDuration = (currentAvg * (total - 1) + duration) / total;
174
+ }
175
+ /**
176
+ * Get stream statistics
177
+ */
178
+ getStreamStats(streamId) {
179
+ const info = this.activeStreams.get(streamId);
180
+ if (!info)
181
+ return null;
182
+ return {
183
+ streamId,
184
+ priority: info.priority,
185
+ bytesReceived: info.bytesReceived,
186
+ bytesSent: info.bytesSent,
187
+ duration: Date.now() - info.startTime,
188
+ state: info.state
189
+ };
190
+ }
191
+ /**
192
+ * Get all statistics
193
+ */
194
+ getStats() {
195
+ const priorityDistribution = new Map();
196
+ for (const [priority, queue] of this.priorityQueues) {
197
+ if (queue.size > 0) {
198
+ priorityDistribution.set(priority, queue.size);
199
+ }
200
+ }
201
+ return {
202
+ ...this.stats,
203
+ priorityDistribution
204
+ };
205
+ }
206
+ /**
207
+ * Check if can accept more streams
208
+ */
209
+ canAcceptStream() {
210
+ return this.stats.activeStreams < this.config.maxConcurrentStreams;
211
+ }
212
+ /**
213
+ * Get load percentage
214
+ */
215
+ getLoad() {
216
+ return (this.stats.activeStreams / this.config.maxConcurrentStreams) * 100;
217
+ }
218
+ }
219
+ /**
220
+ * Flow Control Manager
221
+ * Manages HTTP/2 flow control for optimal throughput
222
+ */
223
+ export class FlowControlManager {
224
+ windowSizes = new Map();
225
+ config;
226
+ constructor(config) {
227
+ this.config = {
228
+ initialWindowSize: config?.initialWindowSize || 65535,
229
+ maxWindowSize: config?.maxWindowSize || 16777215, // 16MB
230
+ minWindowSize: config?.minWindowSize || 16384 // 16KB
231
+ };
232
+ }
233
+ /**
234
+ * Initialize window size for a stream
235
+ */
236
+ initializeWindow(streamId) {
237
+ this.windowSizes.set(streamId, this.config.initialWindowSize);
238
+ }
239
+ /**
240
+ * Update window size
241
+ */
242
+ updateWindow(streamId, delta) {
243
+ const current = this.windowSizes.get(streamId) || this.config.initialWindowSize;
244
+ const newSize = Math.max(this.config.minWindowSize, Math.min(this.config.maxWindowSize, current + delta));
245
+ this.windowSizes.set(streamId, newSize);
246
+ return newSize;
247
+ }
248
+ /**
249
+ * Get current window size
250
+ */
251
+ getWindowSize(streamId) {
252
+ return this.windowSizes.get(streamId) || this.config.initialWindowSize;
253
+ }
254
+ /**
255
+ * Calculate optimal window size based on throughput
256
+ */
257
+ calculateOptimalWindow(throughputBps, rttMs) {
258
+ // Bandwidth-Delay Product
259
+ const bdp = (throughputBps / 8) * (rttMs / 1000);
260
+ return Math.max(this.config.minWindowSize, Math.min(this.config.maxWindowSize, Math.ceil(bdp * 2)));
261
+ }
262
+ /**
263
+ * Clean up closed stream
264
+ */
265
+ cleanup(streamId) {
266
+ this.windowSizes.delete(streamId);
267
+ }
268
+ }
269
+ /**
270
+ * Priority scheduler for optimal stream processing
271
+ */
272
+ export class PriorityScheduler {
273
+ queues = new Map();
274
+ /**
275
+ * Add stream to priority queue
276
+ */
277
+ enqueue(streamId, priority) {
278
+ if (!this.queues.has(priority)) {
279
+ this.queues.set(priority, []);
280
+ }
281
+ this.queues.get(priority).push(streamId);
282
+ }
283
+ /**
284
+ * Get next stream to process
285
+ */
286
+ dequeue() {
287
+ // Process highest priority first
288
+ for (let priority = 256; priority >= 1; priority--) {
289
+ const queue = this.queues.get(priority);
290
+ if (queue && queue.length > 0) {
291
+ return queue.shift();
292
+ }
293
+ }
294
+ return null;
295
+ }
296
+ /**
297
+ * Remove stream from all queues
298
+ */
299
+ remove(streamId) {
300
+ for (const queue of this.queues.values()) {
301
+ const index = queue.indexOf(streamId);
302
+ if (index !== -1) {
303
+ queue.splice(index, 1);
304
+ }
305
+ }
306
+ }
307
+ /**
308
+ * Get queue sizes
309
+ */
310
+ getStats() {
311
+ const stats = new Map();
312
+ for (const [priority, queue] of this.queues) {
313
+ if (queue.length > 0) {
314
+ stats.set(priority, queue.length);
315
+ }
316
+ }
317
+ return stats;
318
+ }
319
+ }
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Lazy Authentication with Session Caching
3
+ * Reduces auth overhead by 5-10% through session caching and lazy validation
4
+ * Phase 3 Optimization
5
+ */
6
+ /**
7
+ * Lazy Authentication Manager
8
+ * Caches validated sessions to avoid repeated authentication overhead
9
+ */
10
+ export class LazyAuthManager {
11
+ config;
12
+ sessions = new Map();
13
+ stats;
14
+ cleanupTimer;
15
+ validationQueue = new Set();
16
+ constructor(config) {
17
+ this.config = {
18
+ enabled: config.enabled,
19
+ ttl: config.ttl || 3600000, // 1 hour default
20
+ maxSessions: config.maxSessions || 1000,
21
+ checkInterval: config.checkInterval || 60000 // 1 minute
22
+ };
23
+ this.stats = {
24
+ totalValidations: 0,
25
+ cacheHits: 0,
26
+ cacheMisses: 0,
27
+ sessionsActive: 0,
28
+ sessionsCleaned: 0,
29
+ avgValidationTime: 0
30
+ };
31
+ if (this.config.enabled) {
32
+ this.startCleanupTimer();
33
+ }
34
+ }
35
+ /**
36
+ * Authenticate a token (lazy validation)
37
+ */
38
+ async authenticate(token, validateFn) {
39
+ if (!this.config.enabled) {
40
+ // No caching, always validate
41
+ const userId = await validateFn(token);
42
+ return this.createSession(token, userId, true);
43
+ }
44
+ // Check cache first
45
+ const cached = this.sessions.get(token);
46
+ if (cached && !this.isExpired(cached)) {
47
+ this.stats.cacheHits++;
48
+ cached.lastAccessedAt = Date.now();
49
+ return cached;
50
+ }
51
+ this.stats.cacheMisses++;
52
+ // Lazy validation: check if already being validated
53
+ if (this.validationQueue.has(token)) {
54
+ // Wait for ongoing validation
55
+ return this.waitForValidation(token);
56
+ }
57
+ // Perform validation
58
+ return this.validateAndCache(token, validateFn);
59
+ }
60
+ /**
61
+ * Validate token and cache the session
62
+ */
63
+ async validateAndCache(token, validateFn) {
64
+ this.validationQueue.add(token);
65
+ try {
66
+ const startTime = Date.now();
67
+ const userId = await validateFn(token);
68
+ const validationTime = Date.now() - startTime;
69
+ // Update average validation time
70
+ this.updateAvgValidationTime(validationTime);
71
+ this.stats.totalValidations++;
72
+ // Create and cache session
73
+ const session = this.createSession(token, userId, true);
74
+ this.cacheSession(session);
75
+ return session;
76
+ }
77
+ catch (error) {
78
+ return null;
79
+ }
80
+ finally {
81
+ this.validationQueue.delete(token);
82
+ }
83
+ }
84
+ /**
85
+ * Wait for ongoing validation
86
+ */
87
+ async waitForValidation(token) {
88
+ // Poll for validation completion (max 5 seconds)
89
+ const maxAttempts = 50;
90
+ let attempts = 0;
91
+ while (this.validationQueue.has(token) && attempts < maxAttempts) {
92
+ await new Promise(resolve => setTimeout(resolve, 100));
93
+ attempts++;
94
+ }
95
+ // Check cache after validation
96
+ const session = this.sessions.get(token);
97
+ return session && !this.isExpired(session) ? session : null;
98
+ }
99
+ /**
100
+ * Create a session object
101
+ */
102
+ createSession(token, userId, validated) {
103
+ const now = Date.now();
104
+ return {
105
+ token,
106
+ userId,
107
+ validated,
108
+ createdAt: now,
109
+ lastAccessedAt: now,
110
+ expiresAt: now + this.config.ttl
111
+ };
112
+ }
113
+ /**
114
+ * Cache a session
115
+ */
116
+ cacheSession(session) {
117
+ // Check max sessions limit
118
+ if (this.sessions.size >= this.config.maxSessions) {
119
+ this.evictOldest();
120
+ }
121
+ this.sessions.set(session.token, session);
122
+ this.stats.sessionsActive = this.sessions.size;
123
+ }
124
+ /**
125
+ * Check if session is expired
126
+ */
127
+ isExpired(session) {
128
+ return Date.now() > session.expiresAt;
129
+ }
130
+ /**
131
+ * Evict oldest session (LRU)
132
+ */
133
+ evictOldest() {
134
+ let oldest = null;
135
+ let oldestToken = null;
136
+ for (const [token, session] of this.sessions) {
137
+ if (!oldest || session.lastAccessedAt < oldest.lastAccessedAt) {
138
+ oldest = session;
139
+ oldestToken = token;
140
+ }
141
+ }
142
+ if (oldestToken) {
143
+ this.sessions.delete(oldestToken);
144
+ this.stats.sessionsCleaned++;
145
+ }
146
+ }
147
+ /**
148
+ * Update average validation time
149
+ */
150
+ updateAvgValidationTime(newTime) {
151
+ const total = this.stats.totalValidations;
152
+ const currentAvg = this.stats.avgValidationTime;
153
+ this.stats.avgValidationTime = (currentAvg * total + newTime) / (total + 1);
154
+ }
155
+ /**
156
+ * Start cleanup timer for expired sessions
157
+ */
158
+ startCleanupTimer() {
159
+ this.cleanupTimer = setInterval(() => {
160
+ this.cleanup();
161
+ }, this.config.checkInterval);
162
+ }
163
+ /**
164
+ * Clean up expired sessions
165
+ */
166
+ cleanup() {
167
+ const now = Date.now();
168
+ let cleaned = 0;
169
+ for (const [token, session] of this.sessions) {
170
+ if (now > session.expiresAt) {
171
+ this.sessions.delete(token);
172
+ cleaned++;
173
+ }
174
+ }
175
+ this.stats.sessionsCleaned += cleaned;
176
+ this.stats.sessionsActive = this.sessions.size;
177
+ }
178
+ /**
179
+ * Invalidate a session
180
+ */
181
+ invalidate(token) {
182
+ return this.sessions.delete(token);
183
+ }
184
+ /**
185
+ * Invalidate all sessions for a user
186
+ */
187
+ invalidateUser(userId) {
188
+ let count = 0;
189
+ for (const [token, session] of this.sessions) {
190
+ if (session.userId === userId) {
191
+ this.sessions.delete(token);
192
+ count++;
193
+ }
194
+ }
195
+ return count;
196
+ }
197
+ /**
198
+ * Get session if exists and valid
199
+ */
200
+ getSession(token) {
201
+ const session = this.sessions.get(token);
202
+ if (!session || this.isExpired(session)) {
203
+ return null;
204
+ }
205
+ session.lastAccessedAt = Date.now();
206
+ return session;
207
+ }
208
+ /**
209
+ * Get statistics
210
+ */
211
+ getStats() {
212
+ return { ...this.stats };
213
+ }
214
+ /**
215
+ * Get cache hit rate
216
+ */
217
+ getCacheHitRate() {
218
+ const total = this.stats.cacheHits + this.stats.cacheMisses;
219
+ return total > 0 ? (this.stats.cacheHits / total) * 100 : 0;
220
+ }
221
+ /**
222
+ * Reset statistics
223
+ */
224
+ resetStats() {
225
+ this.stats = {
226
+ totalValidations: 0,
227
+ cacheHits: 0,
228
+ cacheMisses: 0,
229
+ sessionsActive: this.sessions.size,
230
+ sessionsCleaned: 0,
231
+ avgValidationTime: 0
232
+ };
233
+ }
234
+ /**
235
+ * Clear all sessions
236
+ */
237
+ clear() {
238
+ this.sessions.clear();
239
+ this.stats.sessionsActive = 0;
240
+ }
241
+ /**
242
+ * Destroy manager and cleanup
243
+ */
244
+ destroy() {
245
+ if (this.cleanupTimer) {
246
+ clearInterval(this.cleanupTimer);
247
+ }
248
+ this.clear();
249
+ }
250
+ }
251
+ /**
252
+ * Token-based authentication helper
253
+ */
254
+ export class TokenAuth {
255
+ authManager;
256
+ validateFn;
257
+ constructor(authManager, validateFn) {
258
+ this.authManager = authManager;
259
+ this.validateFn = validateFn;
260
+ }
261
+ /**
262
+ * Authenticate a request
263
+ */
264
+ async authenticate(authHeader) {
265
+ // Extract token from header
266
+ const token = this.extractToken(authHeader);
267
+ if (!token) {
268
+ return null;
269
+ }
270
+ return this.authManager.authenticate(token, this.validateFn);
271
+ }
272
+ /**
273
+ * Extract token from Authorization header
274
+ */
275
+ extractToken(authHeader) {
276
+ if (!authHeader) {
277
+ return null;
278
+ }
279
+ // Support "Bearer <token>" and raw token
280
+ if (authHeader.startsWith('Bearer ')) {
281
+ return authHeader.substring(7);
282
+ }
283
+ return authHeader;
284
+ }
285
+ /**
286
+ * Invalidate token
287
+ */
288
+ invalidate(token) {
289
+ return this.authManager.invalidate(token);
290
+ }
291
+ /**
292
+ * Get statistics
293
+ */
294
+ getStats() {
295
+ return this.authManager.getStats();
296
+ }
297
+ }
298
+ /**
299
+ * Calculate auth overhead reduction
300
+ */
301
+ export function calculateAuthSavings(stats) {
302
+ const hitRate = stats.cacheHits / (stats.cacheHits + stats.cacheMisses);
303
+ const savingsPercentage = hitRate * 100;
304
+ const avgSavedTime = stats.avgValidationTime * hitRate;
305
+ const totalSavedTime = stats.avgValidationTime * stats.cacheHits;
306
+ return {
307
+ savingsPercentage,
308
+ avgSavedTime,
309
+ totalSavedTime
310
+ };
311
+ }