adaptive-memory-multi-model-router 2.14.16 → 2.14.17

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 (38) hide show
  1. package/.a3m-vault.json +23 -0
  2. package/.github/workflows/ci.yml +253 -5
  3. package/.publish-tick +1 -1
  4. package/README.md +15 -17
  5. package/benchmark-results.json +45 -43
  6. package/dist/ensemble.d.ts +21 -0
  7. package/dist/ensemble.js +85 -0
  8. package/dist/index.d.ts +3 -1
  9. package/dist/index.js +12 -4
  10. package/dist/tui/dashboard.js +66 -2
  11. package/dist/tui/dashboard.js.map +1 -1
  12. package/dist/utils/tokenUtils.d.ts +48 -1
  13. package/dist/utils/tokenUtils.js +117 -4
  14. package/dist/utils/tokenUtils.js.map +1 -1
  15. package/docs/CITATIONS.md +2 -2
  16. package/docs/GEO_STATUS.md +43 -157
  17. package/docs/ai-plugin.json +4 -4
  18. package/docs/llms.txt +21 -27
  19. package/docs/sitemap.xml +14 -20
  20. package/package.json +2 -2
  21. package/research/PUBLISH_LOG.md +2 -2
  22. package/sitemap.xml +57 -0
  23. package/src/ensemble.ts +103 -0
  24. package/src/index.ts +13 -3
  25. package/src/tui/dashboard.ts +76 -3
  26. package/src/utils/tokenUtils.ts +142 -4
  27. package/test-council/1-structure-tests.test.js +353 -0
  28. package/test-council/1-structure-tests.test.ts +353 -0
  29. package/test-council/2-edge-case-tests.test.ts +361 -0
  30. package/test-council/3-performance-tests.test.ts +669 -0
  31. package/test-council/4-integration-tests.test.ts +391 -0
  32. package/test-council/5-agent-council-eval.test.ts +413 -0
  33. package/test-council/TEST_COUNCIL_REPORT.md +201 -0
  34. package/test-council/agents/edge-case-agent.ts +363 -0
  35. package/test-council/agents/performance-agent.ts +426 -0
  36. package/test-council/agents/structure-agent.ts +227 -0
  37. package/test-council/council.md +183 -0
  38. package/docs/.well-known/ai-plugin.json +0 -16
@@ -0,0 +1,391 @@
1
+ /**
2
+ * Integration Tests - Full Pipeline and End-to-End Tests
3
+ *
4
+ * Tests that verify the entire system works together correctly.
5
+ */
6
+
7
+ import { describe, it, expect, beforeEach } from 'vitest';
8
+
9
+ // Import all modules
10
+ const {
11
+ routeQuery,
12
+ routeBatch,
13
+ recommendForTask,
14
+ extractQueryFeatures,
15
+ getAvailableProviders,
16
+ healthCheck,
17
+ MemoryTree,
18
+ CostTracker,
19
+ createA3MRouter,
20
+ ProviderRetryHandler,
21
+ DEFAULT_PROVIDERS,
22
+ MODEL_PROFILES,
23
+ countTokens,
24
+ EnsembleOrchestrator,
25
+ } = require('../dist/index.js');
26
+
27
+ // ============================================================
28
+ // INTEGRATION TESTS - REALISTIC SCENARIOS
29
+ // ============================================================
30
+
31
+ describe('1. Integration - Realistic Query Scenarios', () => {
32
+
33
+ describe('Coding assistant workflow', () => {
34
+ it('routes code queries to appropriate provider', () => {
35
+ const result = routeQuery('Write a Python function to calculate fibonacci numbers');
36
+ expect(result.primary_model).toBeTruthy();
37
+ });
38
+
39
+ it('routes debugging queries correctly', () => {
40
+ const result = routeQuery('Fix this Python code: for i in range(10) print(i)');
41
+ expect(result.primary_model).toBeTruthy();
42
+ });
43
+ });
44
+
45
+ describe('Writing assistant workflow', () => {
46
+ it('routes creative writing queries', () => {
47
+ const result = routeQuery('Write a short story about a robot learning to paint');
48
+ expect(result.primary_model).toBeTruthy();
49
+ });
50
+
51
+ it('routes summarization queries', () => {
52
+ const result = routeQuery('Summarize this article about climate change');
53
+ expect(result.primary_model).toBeTruthy();
54
+ });
55
+ });
56
+
57
+ describe('Translation workflow', () => {
58
+ it('routes translation queries', () => {
59
+ const result = routeQuery('Translate this paragraph to Spanish');
60
+ expect(result.primary_model).toBeTruthy();
61
+ });
62
+ });
63
+ });
64
+
65
+ // ============================================================
66
+ // INTEGRATION TESTS - ROUTER FACTORY
67
+ // ============================================================
68
+
69
+ describe('2. Integration - Router Factory', () => {
70
+
71
+ describe('Full router workflow', () => {
72
+ it('creates router with all components', () => {
73
+ const router = createA3MRouter({
74
+ defaultProvider: 'groq',
75
+ enableCache: true,
76
+ enableGuardrails: true,
77
+ costLimit: 10.0
78
+ });
79
+
80
+ expect(router.route).toBeTruthy();
81
+ expect(router.routeBatch).toBeTruthy();
82
+ expect(router.recommendForTask).toBeTruthy();
83
+ expect(router.getAvailableProviders).toBeTruthy();
84
+ expect(router.healthCheck).toBeTruthy();
85
+ expect(router.costTracker).toBeTruthy();
86
+ expect(router.memoryTree).toBeTruthy();
87
+ });
88
+
89
+ it('performs complete query flow', async () => {
90
+ const router = createA3MRouter({});
91
+
92
+ // Route a query
93
+ const routeResult = router.route('What is machine learning?');
94
+ expect(routeResult.primary_model).toBeTruthy();
95
+
96
+ // Add to memory
97
+ await router.memoryTree.add('User asked about machine learning');
98
+
99
+ // Search memory
100
+ const memoryResults = router.memoryTree.search('machine learning');
101
+ expect(Array.isArray(memoryResults)).toBe(true);
102
+ });
103
+
104
+ it('handles batch routing workflow', async () => {
105
+ const router = createA3MRouter({});
106
+
107
+ const queries = [
108
+ 'What is Python?',
109
+ 'Write a hello world program',
110
+ 'Explain photosynthesis'
111
+ ];
112
+
113
+ const results = router.routeBatch(queries);
114
+
115
+ expect(results.length).toBe(queries.length);
116
+
117
+ // Add all to memory (async)
118
+ for (const result of results) {
119
+ await router.memoryTree.add(`Query with result from ${result.primary_model}`);
120
+ }
121
+
122
+ // Verify routing worked
123
+ expect(results.every(r => r.primary_model)).toBe(true);
124
+ });
125
+ });
126
+ });
127
+
128
+ // ============================================================
129
+ // INTEGRATION TESTS - MEMORY OPERATIONS
130
+ // ============================================================
131
+
132
+ describe('3. Integration - Memory Operations', () => {
133
+
134
+ it('adds and searches memory', async () => {
135
+ const memory = new MemoryTree();
136
+
137
+ await memory.add('Python tutorial: variables and types');
138
+ await memory.add('Python tutorial: functions');
139
+ await memory.add('JavaScript basics');
140
+
141
+ const results = memory.search('python tutorial');
142
+ expect(Array.isArray(results)).toBe(true);
143
+ });
144
+
145
+ it('gets memory stats', async () => {
146
+ const memory = new MemoryTree();
147
+
148
+ await memory.add('test entry 1');
149
+ await memory.add('test entry 2');
150
+
151
+ const stats = memory.getStats();
152
+ expect(stats.totalChunks).toBeGreaterThan(0);
153
+ expect(typeof stats.maxDepth).toBe('number');
154
+ expect(typeof stats.treeSize).toBe('number');
155
+ });
156
+ });
157
+
158
+ // ============================================================
159
+ // INTEGRATION TESTS - COST TRACKING
160
+ // ============================================================
161
+
162
+ describe('4. Integration - Cost Tracking', () => {
163
+
164
+ describe('CostTracker basic operations', () => {
165
+ it('creates cost tracker', () => {
166
+ const tracker = new CostTracker();
167
+ expect(tracker).toBeTruthy();
168
+ });
169
+
170
+ it('calculates cost', () => {
171
+ const tracker = new CostTracker();
172
+ const cost = tracker.calculateCost('gpt-4o', 100, 50);
173
+ expect(cost).toBeTruthy();
174
+ expect(typeof cost.total).toBe('number');
175
+ });
176
+
177
+ it('records request', () => {
178
+ const tracker = new CostTracker();
179
+ const snapshot = tracker.record('openai', 'gpt-4o', 100, 50);
180
+ expect(snapshot).toBeTruthy();
181
+ expect(snapshot.total_cost).toBeGreaterThan(0);
182
+ });
183
+
184
+ it('gets summary', () => {
185
+ const tracker = new CostTracker();
186
+ tracker.record('openai', 'gpt-4o', 100, 50);
187
+ const summary = tracker.getSummary();
188
+ expect(summary).toBeTruthy();
189
+ expect(summary.request_count).toBe(1);
190
+ });
191
+ });
192
+ });
193
+
194
+ // ============================================================
195
+ // INTEGRATION TESTS - PROVIDER HEALTH
196
+ // ============================================================
197
+
198
+ describe('5. Integration - Provider Health', () => {
199
+
200
+ describe('Health check integration', () => {
201
+ it('healthCheck function is available', () => {
202
+ expect(typeof healthCheck).toBe('function');
203
+ });
204
+
205
+ it('getAvailableProviders shows all providers', () => {
206
+ const providers = getAvailableProviders();
207
+ expect(Object.keys(providers).length).toBeGreaterThan(0);
208
+ });
209
+
210
+ it('recommendForTask works for different task types', () => {
211
+ const tasks = ['coding', 'writing', 'analysis', 'chat', 'translation'];
212
+
213
+ for (const task of tasks) {
214
+ const rec = recommendForTask(task);
215
+ expect(rec.primary).toBeTruthy();
216
+ expect(Array.isArray(rec.fallbacks)).toBe(true);
217
+ }
218
+ });
219
+ });
220
+ });
221
+
222
+ // ============================================================
223
+ // INTEGRATION TESTS - ERROR RECOVERY
224
+ // ============================================================
225
+
226
+ describe('6. Integration - Error Recovery', () => {
227
+
228
+ describe('Retry handler integration', () => {
229
+ let handler: ProviderRetryHandler;
230
+
231
+ beforeEach(() => {
232
+ handler = new ProviderRetryHandler();
233
+ });
234
+
235
+ it('succeeds after transient failure', async () => {
236
+ const flakyFn = () => Promise.resolve('success');
237
+
238
+ const result = await handler.executeWithRetry('groq', flakyFn);
239
+ expect(result).toBe('success');
240
+ });
241
+
242
+ it('validates context window', () => {
243
+ const result = handler.validateContextWindow('groq', 'short prompt');
244
+ expect(result.valid).toBe(true);
245
+ });
246
+ });
247
+ });
248
+
249
+ // ============================================================
250
+ // INTEGRATION TESTS - CONCURRENT OPERATIONS
251
+ // ============================================================
252
+
253
+ describe('7. Integration - Concurrent Operations', () => {
254
+
255
+ describe('Parallel query processing', () => {
256
+ it('handles parallel routeQuery calls', async () => {
257
+ const promises = Array(20).fill(null).map((_, i) =>
258
+ Promise.resolve(routeQuery(`concurrent query ${i}`))
259
+ );
260
+
261
+ const results = await Promise.all(promises);
262
+
263
+ expect(results.length).toBe(20);
264
+ for (const r of results) {
265
+ expect(r.primary_model).toBeTruthy();
266
+ }
267
+ });
268
+ });
269
+ });
270
+
271
+ // ============================================================
272
+ // INTEGRATION TESTS - DATA PIPELINES
273
+ // ============================================================
274
+
275
+ describe('8. Integration - Data Pipelines', () => {
276
+
277
+ describe('Query feature extraction pipeline', () => {
278
+ it('extracts features consistently', () => {
279
+ const query = 'Write a Python function to sort an array';
280
+
281
+ const features1 = extractQueryFeatures(query);
282
+ const features2 = extractQueryFeatures(query);
283
+
284
+ expect(features1.has_code).toBe(features2.has_code);
285
+ });
286
+ });
287
+
288
+ describe('Token counting pipeline', () => {
289
+ it('counts tokens consistently', () => {
290
+ const text = 'This is a test sentence for token counting consistency.';
291
+
292
+ const tokens1 = countTokens(text);
293
+ const tokens2 = countTokens(text);
294
+
295
+ expect(tokens1).toBe(tokens2);
296
+ });
297
+ });
298
+ });
299
+
300
+ // ============================================================
301
+ // INTEGRATION TESTS - END-TO-END SCENARIOS
302
+ // ============================================================
303
+
304
+ describe('9. Integration - End-to-End Scenarios', () => {
305
+
306
+ describe('Complete user workflow', () => {
307
+ it('simulates complete conversation flow', () => {
308
+ const router = createA3MRouter({});
309
+
310
+ // User asks coding question
311
+ const q1 = router.route('Write a Python function to reverse a string');
312
+ expect(q1.primary_model).toBeTruthy();
313
+
314
+ // User asks follow-up
315
+ const q2 = router.route('Now add error handling');
316
+ expect(q2.primary_model).toBeTruthy();
317
+
318
+ // Verify both routed successfully
319
+ expect(q1.primary_model).toBeTruthy();
320
+ expect(q2.primary_model).toBeTruthy();
321
+ });
322
+
323
+ it('simulates multi-turn conversation with memory', async () => {
324
+ const router = createA3MRouter({});
325
+
326
+ // First interaction
327
+ await router.memoryTree.add('User asked about web development');
328
+
329
+ // Second interaction
330
+ await router.memoryTree.add('User followed up on HTML question');
331
+
332
+ // Query
333
+ const result = router.route('How do I center a div?');
334
+ expect(result.primary_model).toBeTruthy();
335
+
336
+ // Verify memory works
337
+ const memoryResults = router.memoryTree.search('web');
338
+ expect(Array.isArray(memoryResults)).toBe(true);
339
+ });
340
+
341
+ it('simulates batch processing workflow', async () => {
342
+ const router = createA3MRouter({});
343
+
344
+ const queries = [
345
+ 'What is React?',
346
+ 'Explain TypeScript',
347
+ 'Write a REST API example',
348
+ 'Compare SQL and NoSQL',
349
+ 'How does HTTPS work?'
350
+ ];
351
+
352
+ // Route all queries
353
+ const routes = router.routeBatch(queries);
354
+
355
+ // Add to memory
356
+ for (const route of routes) {
357
+ await router.memoryTree.add(`Query about something from ${route.primary_model}`);
358
+ }
359
+
360
+ // Verify batch processed
361
+ expect(routes.length).toBe(queries.length);
362
+
363
+ // Verify memory has entries
364
+ const memoryStats = router.memoryTree.getStats();
365
+ expect(memoryStats.totalChunks).toBeGreaterThanOrEqual(0);
366
+ });
367
+ });
368
+ });
369
+
370
+ // ============================================================
371
+ // INTEGRATION TESTS - MODEL PROFILES
372
+ // ============================================================
373
+
374
+ describe('10. Integration - Model Profiles', () => {
375
+
376
+ describe('Model profile access', () => {
377
+ it('has profiles for multiple providers', () => {
378
+ const providerSet = new Set(
379
+ Object.values(MODEL_PROFILES).map((p: any) => p.provider)
380
+ );
381
+
382
+ expect(providerSet.size).toBeGreaterThan(1);
383
+ });
384
+
385
+ it('model profiles have strengths array', () => {
386
+ for (const profile of Object.values(MODEL_PROFILES) as any[]) {
387
+ expect(Array.isArray(profile.strengths)).toBe(true);
388
+ }
389
+ });
390
+ });
391
+ });