adaptive-memory-multi-model-router 1.9.4 → 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.
Files changed (130) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
  2. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +37 -0
  4. package/.github/PULL_REQUEST_TEMPLATE.md +44 -0
  5. package/.github/workflows/npm-stats-validation.yml +152 -0
  6. package/.github/workflows/pages.yml +37 -0
  7. package/CHANGELOG.md +122 -0
  8. package/CODE_OF_CONDUCT.md +128 -0
  9. package/CONTRIBUTING.md +110 -0
  10. package/LAUNCH-PAIN-DRIVEN.md +339 -0
  11. package/LAUNCH.md +575 -0
  12. package/POPULARITY_BOOSTERS.md +285 -0
  13. package/README.md +231 -300
  14. package/SECURITY.md +69 -0
  15. package/articles/CONTENT_STRUCTURE.md +292 -0
  16. package/articles/DEVTO_COST_GUIDE.md +473 -0
  17. package/articles/DEVTO_FINAL.md +416 -0
  18. package/articles/DEVTO_MULTI_PROVIDER.md +542 -0
  19. package/articles/HN_10X_BETTER.md +430 -0
  20. package/articles/HN_CHINESE_STYLE.md +308 -0
  21. package/articles/HN_FINAL.md +199 -0
  22. package/articles/HN_POSTED_VERSION.md +56 -0
  23. package/articles/HN_RESEARCH.md +364 -0
  24. package/articles/PAIN-DRIVEN-devto-v2.md +308 -0
  25. package/articles/PAIN-DRIVEN-devto-v3.md +268 -0
  26. package/articles/PAIN-DRIVEN-devto.md +242 -0
  27. package/articles/PAIN-DRIVEN-hackernews-v2.md +138 -0
  28. package/articles/PAIN-DRIVEN-hackernews-v3.md +151 -0
  29. package/articles/PAIN-DRIVEN-hackernews.md +131 -0
  30. package/articles/PAIN-DRIVEN-reddit-v2.md +301 -0
  31. package/articles/PAIN-DRIVEN-reddit-v3.md +236 -0
  32. package/articles/PAIN-DRIVEN-reddit.md +218 -0
  33. package/articles/PAIN-DRIVEN-twitter-v2.md +110 -0
  34. package/articles/PAIN-DRIVEN-twitter-v3.md +121 -0
  35. package/articles/PAIN-DRIVEN-twitter.md +120 -0
  36. package/articles/PORTKEY_VS_A3M.md +147 -0
  37. package/articles/REDDIT_FINAL.md +232 -0
  38. package/articles/TWITTER_FINAL.md +167 -0
  39. package/articles/WHY_10X_BETTER.md +261 -0
  40. package/articles/WHY_CHINESE_STYLE_BETTER.md +323 -0
  41. package/articles/ai-discoverability-llm-routing.md +210 -0
  42. package/articles/devto-llm-routing.md +109 -0
  43. package/articles/hackernews-show-hn.md +65 -0
  44. package/articles/hashnode-llm-cost-optimization.md +125 -0
  45. package/articles/medium-building-llm-router.md +205 -0
  46. package/articles/reddit-ml.md +86 -0
  47. package/articles/twitter-thread-cost-savings.md +98 -0
  48. package/articles/youtube-tutorial-script.md +262 -0
  49. package/assets/banner.svg +109 -0
  50. package/assets/logo.svg +68 -0
  51. package/assets/social-preview.svg +64 -0
  52. package/demo/demo-script.md +53 -0
  53. package/dist/analytics/costAnalytics.d.ts +77 -0
  54. package/dist/analytics/costAnalytics.d.ts.map +1 -0
  55. package/dist/analytics/costAnalytics.js +219 -0
  56. package/dist/analytics/costAnalytics.js.map +1 -0
  57. package/dist/cache/semanticCache.d.ts +62 -0
  58. package/dist/cache/semanticCache.d.ts.map +1 -0
  59. package/dist/cache/semanticCache.js +176 -0
  60. package/dist/cache/semanticCache.js.map +1 -0
  61. package/dist/cli.js +35 -0
  62. package/dist/geo/generativeEngineOptimization.js +321 -0
  63. package/dist/geo/geoRouter.js +387 -0
  64. package/dist/index.d.ts +4 -723
  65. package/dist/index.js +11 -344
  66. package/dist/index.js.map +1 -1
  67. package/dist/integrations/langchainAdapter.d.ts +146 -0
  68. package/dist/integrations/langchainAdapter.d.ts.map +1 -0
  69. package/dist/integrations/langchainAdapter.js +731 -0
  70. package/dist/integrations/langchainAdapter.js.map +1 -0
  71. package/dist/integrations/oauth.d.ts +69 -0
  72. package/dist/integrations/oauth.d.ts.map +1 -0
  73. package/dist/integrations/oauth.js +225 -21
  74. package/dist/integrations/oauth.js.map +1 -0
  75. package/dist/memory/autoFetch.d.ts +39 -0
  76. package/dist/memory/autoFetch.d.ts.map +1 -0
  77. package/dist/memory/autoFetch.js +80 -88
  78. package/dist/memory/autoFetch.js.map +1 -0
  79. package/dist/memory/memoryTree.d.ts +76 -0
  80. package/dist/memory/memoryTree.d.ts.map +1 -0
  81. package/dist/memory/memoryTree.js +185 -130
  82. package/dist/memory/memoryTree.js.map +1 -0
  83. package/dist/memory/obsidianVault.d.ts +71 -0
  84. package/dist/memory/obsidianVault.d.ts.map +1 -0
  85. package/dist/memory/obsidianVault.js +207 -22
  86. package/dist/memory/obsidianVault.js.map +1 -0
  87. package/dist/providers/providerConfig.d.ts +49 -0
  88. package/dist/providers/providerConfig.d.ts.map +1 -0
  89. package/dist/providers/providerConfig.js +806 -401
  90. package/dist/providers/providerConfig.js.map +1 -0
  91. package/dist/security/guardrails.d.ts +76 -0
  92. package/dist/security/guardrails.d.ts.map +1 -0
  93. package/dist/security/guardrails.js +479 -0
  94. package/dist/security/guardrails.js.map +1 -0
  95. package/dist/security/inputValidation.js +351 -0
  96. package/dist/server/dashboard.d.ts +58 -0
  97. package/dist/server/dashboard.d.ts.map +1 -0
  98. package/dist/server/dashboard.js +553 -0
  99. package/dist/server/dashboard.js.map +1 -0
  100. package/dist/server/modelMapper.d.ts +43 -0
  101. package/dist/server/modelMapper.d.ts.map +1 -0
  102. package/dist/server/modelMapper.js +154 -0
  103. package/dist/server/modelMapper.js.map +1 -0
  104. package/dist/server/proxyServer.d.ts +41 -0
  105. package/dist/server/proxyServer.d.ts.map +1 -0
  106. package/dist/server/proxyServer.js +932 -0
  107. package/dist/server/proxyServer.js.map +1 -0
  108. package/dist/skills/__tests__/skill_manager.test.d.ts +2 -0
  109. package/dist/skills/__tests__/skill_manager.test.d.ts.map +1 -0
  110. package/dist/skills/__tests__/skill_manager.test.js +268 -0
  111. package/dist/skills/__tests__/skill_manager.test.js.map +1 -0
  112. package/docs/geo/GENERATIVE_ENGINE_OPTIMIZATION.md +232 -0
  113. package/docs-site/index.html +347 -0
  114. package/llms.txt +138 -0
  115. package/package.json +72 -7
  116. package/playground/README.md +51 -0
  117. package/playground/codesandbox.json +12 -0
  118. package/playground/index.js +39 -0
  119. package/scripts/update-npm-badges.js +158 -0
  120. package/src/analytics/costAnalytics.ts +304 -0
  121. package/src/cache/semanticCache.ts +221 -0
  122. package/src/index.ts +6 -0
  123. package/src/integrations/langchainAdapter.ts +955 -0
  124. package/src/providers/providerConfig.ts +923 -0
  125. package/src/security/guardrails.ts +585 -0
  126. package/src/server/dashboard.ts +610 -0
  127. package/src/server/modelMapper.ts +182 -0
  128. package/src/server/proxyServer.ts +1105 -0
  129. package/src/types/langchain.d.ts +83 -0
  130. package/tsconfig.build.json +20 -0
@@ -0,0 +1,387 @@
1
+ "use strict";
2
+ /**
3
+ * A3M Router - Geo-Location Based Routing
4
+ *
5
+ * Route LLM queries to providers based on geographic location:
6
+ * - Latency optimization (nearest provider)
7
+ * - Data sovereignty (EU data stays in EU)
8
+ * - Compliance (GDPR, CCPA)
9
+ * - Regional provider preferences
10
+ */
11
+
12
+ // Provider regions and data centers
13
+ const PROVIDER_REGIONS = {
14
+ groq: {
15
+ regions: ['us-west', 'us-east', 'eu-west'],
16
+ dataCenters: {
17
+ 'us-west': { lat: 37.7749, lon: -122.4194, location: 'San Francisco' },
18
+ 'us-east': { lat: 40.7128, lon: -74.0060, location: 'New York' },
19
+ 'eu-west': { lat: 53.3498, lon: -6.2603, location: 'Dublin' },
20
+ },
21
+ gdprCompliant: true,
22
+ soc2Compliant: true,
23
+ },
24
+ cerebras: {
25
+ regions: ['us-west', 'us-central'],
26
+ dataCenters: {
27
+ 'us-west': { lat: 37.7749, lon: -122.4194, location: 'San Francisco' },
28
+ 'us-central': { lat: 41.8781, lon: -87.6298, location: 'Chicago' },
29
+ },
30
+ gdprCompliant: false,
31
+ soc2Compliant: true,
32
+ },
33
+ mistral: {
34
+ regions: ['eu-west', 'eu-central'],
35
+ dataCenters: {
36
+ 'eu-west': { lat: 48.8566, lon: 2.3522, location: 'Paris' },
37
+ 'eu-central': { lat: 50.1109, lon: 8.6821, location: 'Frankfurt' },
38
+ },
39
+ gdprCompliant: true,
40
+ soc2Compliant: true,
41
+ },
42
+ openai: {
43
+ regions: ['us-west', 'us-east', 'eu-west', 'apac'],
44
+ dataCenters: {
45
+ 'us-west': { lat: 37.7749, lon: -122.4194, location: 'San Francisco' },
46
+ 'us-east': { lat: 40.7128, lon: -74.0060, location: 'New York' },
47
+ 'eu-west': { lat: 53.3498, lon: -6.2603, location: 'Dublin' },
48
+ 'apac': { lat: 1.3521, lon: 103.8198, location: 'Singapore' },
49
+ },
50
+ gdprCompliant: true,
51
+ soc2Compliant: true,
52
+ },
53
+ anthropic: {
54
+ regions: ['us-west', 'us-east'],
55
+ dataCenters: {
56
+ 'us-west': { lat: 37.7749, lon: -122.4194, location: 'San Francisco' },
57
+ 'us-east': { lat: 40.7128, lon: -74.0060, location: 'New York' },
58
+ },
59
+ gdprCompliant: false,
60
+ soc2Compliant: true,
61
+ },
62
+ google: {
63
+ regions: ['us-central', 'us-east', 'eu-west', 'eu-central', 'apac', 'apac-east'],
64
+ dataCenters: {
65
+ 'us-central': { lat: 41.8781, lon: -87.6298, location: 'Iowa' },
66
+ 'us-east': { lat: 33.7490, lon: -84.3880, location: 'Georgia' },
67
+ 'eu-west': { lat: 53.3498, lon: -6.2603, location: 'Dublin' },
68
+ 'eu-central': { lat: 50.4500, lon: 3.8180, location: 'Belgium' },
69
+ 'apac': { lat: 1.3521, lon: 103.8198, location: 'Singapore' },
70
+ 'apac-east': { lat: 35.6762, lon: 139.6503, location: 'Tokyo' },
71
+ },
72
+ gdprCompliant: true,
73
+ soc2Compliant: true,
74
+ },
75
+ };
76
+
77
+ // Regional compliance requirements
78
+ const COMPLIANCE_RULES = {
79
+ gdpr: {
80
+ regions: ['EU', 'EEA'],
81
+ required: ['gdprCompliant'],
82
+ dataResidency: true,
83
+ },
84
+ ccpa: {
85
+ regions: ['California'],
86
+ required: ['privacyPolicy'],
87
+ dataResidency: false,
88
+ },
89
+ hipaa: {
90
+ regions: ['US-Healthcare'],
91
+ required: ['hipaaCompliant', 'baa'],
92
+ dataResidency: true,
93
+ },
94
+ fedramp: {
95
+ regions: ['US-Government'],
96
+ required: ['fedrampAuthorized'],
97
+ dataResidency: true,
98
+ },
99
+ };
100
+
101
+ class GeoRouter {
102
+ constructor(options = {}) {
103
+ this.options = {
104
+ defaultRegion: options.defaultRegion || 'us-east',
105
+ enforceGDPR: options.enforceGDPR || false,
106
+ enforceCCPA: options.enforceCCPA || false,
107
+ dataResidency: options.dataResidency || null, // 'EU', 'US', etc.
108
+ preferLowLatency: options.preferLowLatency !== false,
109
+ maxLatencyMs: options.maxLatencyMs || 500,
110
+ ...options,
111
+ };
112
+ }
113
+
114
+ /**
115
+ * Calculate distance between two points using Haversine formula
116
+ */
117
+ calculateDistance(lat1, lon1, lat2, lon2) {
118
+ const R = 6371; // Earth's radius in km
119
+ const dLat = this.toRadians(lat2 - lat1);
120
+ const dLon = this.toRadians(lon2 - lon1);
121
+ const a =
122
+ Math.sin(dLat / 2) * Math.sin(dLat / 2) +
123
+ Math.cos(this.toRadians(lat1)) *
124
+ Math.cos(this.toRadians(lat2)) *
125
+ Math.sin(dLon / 2) *
126
+ Math.sin(dLon / 2);
127
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
128
+ return R * c;
129
+ }
130
+
131
+ toRadians(degrees) {
132
+ return (degrees * Math.PI) / 180;
133
+ }
134
+
135
+ /**
136
+ * Estimate latency based on distance
137
+ */
138
+ estimateLatency(distanceKm) {
139
+ // Rough estimate: 1ms per 100km + 50ms base
140
+ return Math.round(distanceKm / 100 + 50);
141
+ }
142
+
143
+ /**
144
+ * Get user's location from IP or explicit coordinates
145
+ */
146
+ async getUserLocation(ipAddress, explicitCoords = null) {
147
+ if (explicitCoords) {
148
+ return {
149
+ lat: explicitCoords.lat,
150
+ lon: explicitCoords.lon,
151
+ region: explicitCoords.region || this.inferRegion(explicitCoords.lat, explicitCoords.lon),
152
+ country: explicitCoords.country,
153
+ source: 'explicit',
154
+ };
155
+ }
156
+
157
+ // In production, use a geolocation service
158
+ // For now, return default
159
+ return {
160
+ lat: 40.7128,
161
+ lon: -74.006,
162
+ region: 'us-east',
163
+ country: 'US',
164
+ source: 'default',
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Infer region from coordinates
170
+ */
171
+ inferRegion(lat, lon) {
172
+ // Rough region inference
173
+ if (lat > 25 && lat < 50 && lon > -130 && lon < -60) return 'us-east';
174
+ if (lat > 25 && lat < 50 && lon > -125 && lon < -115) return 'us-west';
175
+ if (lat > 35 && lat < 70 && lon > -10 && lon < 40) return 'eu-west';
176
+ if (lat > 10 && lat < 40 && lon > 100 && lon < 150) return 'apac';
177
+ return this.options.defaultRegion;
178
+ }
179
+
180
+ /**
181
+ * Check if provider meets compliance requirements
182
+ */
183
+ checkCompliance(providerId, compliance = []) {
184
+ const provider = PROVIDER_REGIONS[providerId];
185
+ if (!provider) return { compliant: false, reason: 'Unknown provider' };
186
+
187
+ const results = {
188
+ compliant: true,
189
+ checks: {},
190
+ failed: [],
191
+ };
192
+
193
+ for (const req of compliance) {
194
+ const rule = COMPLIANCE_RULES[req];
195
+ if (!rule) continue;
196
+
197
+ for (const requirement of rule.required) {
198
+ const check = this.checkRequirement(provider, requirement);
199
+ results.checks[requirement] = check;
200
+
201
+ if (!check.passed) {
202
+ results.compliant = false;
203
+ results.failed.push({ requirement, reason: check.reason });
204
+ }
205
+ }
206
+ }
207
+
208
+ return results;
209
+ }
210
+
211
+ checkRequirement(provider, requirement) {
212
+ switch (requirement) {
213
+ case 'gdprCompliant':
214
+ return {
215
+ passed: provider.gdprCompliant,
216
+ reason: provider.gdprCompliant ? null : 'Provider not GDPR compliant',
217
+ };
218
+ case 'soc2Compliant':
219
+ return {
220
+ passed: provider.soc2Compliant,
221
+ reason: provider.soc2Compliant ? null : 'Provider not SOC2 compliant',
222
+ };
223
+ default:
224
+ return { passed: true, reason: null };
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Find nearest provider data center
230
+ */
231
+ findNearestRegion(providerId, userLocation) {
232
+ const provider = PROVIDER_REGIONS[providerId];
233
+ if (!provider) return null;
234
+
235
+ let nearest = null;
236
+ let minDistance = Infinity;
237
+
238
+ for (const [region, coords] of Object.entries(provider.dataCenters)) {
239
+ const distance = this.calculateDistance(
240
+ userLocation.lat,
241
+ userLocation.lon,
242
+ coords.lat,
243
+ coords.lon
244
+ );
245
+
246
+ if (distance < minDistance) {
247
+ minDistance = distance;
248
+ nearest = {
249
+ region,
250
+ distance,
251
+ estimatedLatency: this.estimateLatency(distance),
252
+ location: coords.location,
253
+ };
254
+ }
255
+ }
256
+
257
+ return nearest;
258
+ }
259
+
260
+ /**
261
+ * Route query based on geographic location
262
+ */
263
+ async routeByLocation(query, options = {}) {
264
+ const userLocation = await this.getUserLocation(
265
+ options.ipAddress,
266
+ options.coordinates
267
+ );
268
+
269
+ const availableProviders = options.providers || Object.keys(PROVIDER_REGIONS);
270
+ const candidates = [];
271
+
272
+ for (const providerId of availableProviders) {
273
+ const provider = PROVIDER_REGIONS[providerId];
274
+ if (!provider) continue;
275
+
276
+ // Check compliance
277
+ if (options.compliance?.length > 0) {
278
+ const compliance = this.checkCompliance(providerId, options.compliance);
279
+ if (!compliance.compliant) {
280
+ continue;
281
+ }
282
+ }
283
+
284
+ // Check data residency
285
+ if (this.options.dataResidency) {
286
+ const hasRegionInResidency = provider.regions.some((r) =>
287
+ r.toLowerCase().includes(this.options.dataResidency.toLowerCase())
288
+ );
289
+ if (!hasRegionInResidency) continue;
290
+ }
291
+
292
+ // Find nearest region
293
+ const nearest = this.findNearestRegion(providerId, userLocation);
294
+ if (!nearest) continue;
295
+
296
+ // Check latency constraint
297
+ if (nearest.estimatedLatency > this.options.maxLatencyMs) {
298
+ continue;
299
+ }
300
+
301
+ candidates.push({
302
+ provider: providerId,
303
+ region: nearest.region,
304
+ distance: nearest.distance,
305
+ estimatedLatency: nearest.estimatedLatency,
306
+ location: nearest.location,
307
+ gdprCompliant: provider.gdprCompliant,
308
+ });
309
+ }
310
+
311
+ // Sort by latency
312
+ candidates.sort((a, b) => a.estimatedLatency - b.estimatedLatency);
313
+
314
+ return {
315
+ userLocation,
316
+ candidates,
317
+ recommended: candidates[0] || null,
318
+ alternatives: candidates.slice(1, 4),
319
+ };
320
+ }
321
+
322
+ /**
323
+ * Get provider regions info
324
+ */
325
+ getProviderRegions(providerId) {
326
+ return PROVIDER_REGIONS[providerId] || null;
327
+ }
328
+
329
+ /**
330
+ * List all available regions
331
+ */
332
+ listRegions() {
333
+ const regions = new Set();
334
+ for (const provider of Object.values(PROVIDER_REGIONS)) {
335
+ for (const region of provider.regions) {
336
+ regions.add(region);
337
+ }
338
+ }
339
+ return Array.from(regions).sort();
340
+ }
341
+
342
+ /**
343
+ * Get compliance status for all providers
344
+ */
345
+ getComplianceStatus() {
346
+ const status = {};
347
+ for (const [providerId, provider] of Object.entries(PROVIDER_REGIONS)) {
348
+ status[providerId] = {
349
+ gdpr: provider.gdprCompliant,
350
+ soc2: provider.soc2Compliant,
351
+ regions: provider.regions,
352
+ };
353
+ }
354
+ return status;
355
+ }
356
+ }
357
+
358
+ // Convenience functions
359
+ async function routeByLocation(query, options = {}) {
360
+ const router = new GeoRouter(options);
361
+ return router.routeByLocation(query, options);
362
+ }
363
+
364
+ function getProviderRegions(providerId) {
365
+ const router = new GeoRouter();
366
+ return router.getProviderRegions(providerId);
367
+ }
368
+
369
+ function listRegions() {
370
+ const router = new GeoRouter();
371
+ return router.listRegions();
372
+ }
373
+
374
+ function getComplianceStatus() {
375
+ const router = new GeoRouter();
376
+ return router.getComplianceStatus();
377
+ }
378
+
379
+ module.exports = {
380
+ GeoRouter,
381
+ routeByLocation,
382
+ getProviderRegions,
383
+ listRegions,
384
+ getComplianceStatus,
385
+ PROVIDER_REGIONS,
386
+ COMPLIANCE_RULES,
387
+ };