adaptive-memory-multi-model-router 1.9.5 → 2.0.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 (122) 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/DEVTO_V2_ANNOUNCEMENT.md +160 -0
  20. package/articles/HN_10X_BETTER.md +430 -0
  21. package/articles/HN_CHINESE_STYLE.md +308 -0
  22. package/articles/HN_FINAL.md +199 -0
  23. package/articles/HN_POSTED_VERSION.md +56 -0
  24. package/articles/HN_RESEARCH.md +364 -0
  25. package/articles/PAIN-DRIVEN-devto-v2.md +308 -0
  26. package/articles/PAIN-DRIVEN-devto-v3.md +268 -0
  27. package/articles/PAIN-DRIVEN-devto.md +242 -0
  28. package/articles/PAIN-DRIVEN-hackernews-v2.md +138 -0
  29. package/articles/PAIN-DRIVEN-hackernews-v3.md +151 -0
  30. package/articles/PAIN-DRIVEN-hackernews.md +131 -0
  31. package/articles/PAIN-DRIVEN-reddit-v2.md +301 -0
  32. package/articles/PAIN-DRIVEN-reddit-v3.md +236 -0
  33. package/articles/PAIN-DRIVEN-reddit.md +218 -0
  34. package/articles/PAIN-DRIVEN-twitter-v2.md +110 -0
  35. package/articles/PAIN-DRIVEN-twitter-v3.md +121 -0
  36. package/articles/PAIN-DRIVEN-twitter.md +120 -0
  37. package/articles/PORTKEY_VS_A3M.md +147 -0
  38. package/articles/REDDIT_FINAL.md +232 -0
  39. package/articles/TWITTER_FINAL.md +167 -0
  40. package/articles/WHY_10X_BETTER.md +261 -0
  41. package/articles/WHY_CHINESE_STYLE_BETTER.md +323 -0
  42. package/articles/hashnode-llm-cost-optimization.md +125 -0
  43. package/articles/medium-building-llm-router.md +205 -0
  44. package/articles/twitter-thread-cost-savings.md +98 -0
  45. package/articles/youtube-tutorial-script.md +262 -0
  46. package/assets/banner.svg +109 -0
  47. package/assets/logo.svg +68 -0
  48. package/assets/social-preview.svg +64 -0
  49. package/demo/demo-script.md +53 -0
  50. package/dist/analytics/costAnalytics.d.ts +77 -0
  51. package/dist/analytics/costAnalytics.d.ts.map +1 -0
  52. package/dist/analytics/costAnalytics.js +219 -0
  53. package/dist/analytics/costAnalytics.js.map +1 -0
  54. package/dist/cache/semanticCache.d.ts +62 -0
  55. package/dist/cache/semanticCache.d.ts.map +1 -0
  56. package/dist/cache/semanticCache.js +176 -0
  57. package/dist/cache/semanticCache.js.map +1 -0
  58. package/dist/cli.js +35 -0
  59. package/dist/index.d.ts +30 -722
  60. package/dist/index.js +76 -355
  61. package/dist/index.js.map +1 -1
  62. package/dist/integrations/langchainAdapter.d.ts +146 -0
  63. package/dist/integrations/langchainAdapter.d.ts.map +1 -0
  64. package/dist/integrations/langchainAdapter.js +731 -0
  65. package/dist/integrations/langchainAdapter.js.map +1 -0
  66. package/dist/integrations/oauth.d.ts +69 -0
  67. package/dist/integrations/oauth.d.ts.map +1 -0
  68. package/dist/integrations/oauth.js +225 -21
  69. package/dist/integrations/oauth.js.map +1 -0
  70. package/dist/memory/autoFetch.d.ts +39 -0
  71. package/dist/memory/autoFetch.d.ts.map +1 -0
  72. package/dist/memory/autoFetch.js +80 -88
  73. package/dist/memory/autoFetch.js.map +1 -0
  74. package/dist/memory/memoryTree.d.ts +76 -0
  75. package/dist/memory/memoryTree.d.ts.map +1 -0
  76. package/dist/memory/memoryTree.js +185 -130
  77. package/dist/memory/memoryTree.js.map +1 -0
  78. package/dist/memory/obsidianVault.d.ts +71 -0
  79. package/dist/memory/obsidianVault.d.ts.map +1 -0
  80. package/dist/memory/obsidianVault.js +207 -22
  81. package/dist/memory/obsidianVault.js.map +1 -0
  82. package/dist/providers/providerConfig.d.ts +49 -0
  83. package/dist/providers/providerConfig.d.ts.map +1 -0
  84. package/dist/providers/providerConfig.js +806 -401
  85. package/dist/providers/providerConfig.js.map +1 -0
  86. package/dist/security/guardrails.d.ts +76 -0
  87. package/dist/security/guardrails.d.ts.map +1 -0
  88. package/dist/security/guardrails.js +479 -0
  89. package/dist/security/guardrails.js.map +1 -0
  90. package/dist/server/dashboard.d.ts +58 -0
  91. package/dist/server/dashboard.d.ts.map +1 -0
  92. package/dist/server/dashboard.js +553 -0
  93. package/dist/server/dashboard.js.map +1 -0
  94. package/dist/server/modelMapper.d.ts +43 -0
  95. package/dist/server/modelMapper.d.ts.map +1 -0
  96. package/dist/server/modelMapper.js +154 -0
  97. package/dist/server/modelMapper.js.map +1 -0
  98. package/dist/server/proxyServer.d.ts +41 -0
  99. package/dist/server/proxyServer.d.ts.map +1 -0
  100. package/dist/server/proxyServer.js +932 -0
  101. package/dist/server/proxyServer.js.map +1 -0
  102. package/dist/skills/__tests__/skill_manager.test.d.ts +2 -0
  103. package/dist/skills/__tests__/skill_manager.test.d.ts.map +1 -0
  104. package/dist/skills/__tests__/skill_manager.test.js +268 -0
  105. package/dist/skills/__tests__/skill_manager.test.js.map +1 -0
  106. package/docs-site/index.html +347 -0
  107. package/package.json +53 -7
  108. package/playground/README.md +51 -0
  109. package/playground/codesandbox.json +12 -0
  110. package/playground/index.js +39 -0
  111. package/scripts/update-npm-badges.js +158 -0
  112. package/src/analytics/costAnalytics.ts +304 -0
  113. package/src/cache/semanticCache.ts +221 -0
  114. package/src/index.ts +99 -0
  115. package/src/integrations/langchainAdapter.ts +955 -0
  116. package/src/providers/providerConfig.ts +923 -0
  117. package/src/security/guardrails.ts +585 -0
  118. package/src/server/dashboard.ts +610 -0
  119. package/src/server/modelMapper.ts +182 -0
  120. package/src/server/proxyServer.ts +1105 -0
  121. package/src/types/langchain.d.ts +83 -0
  122. package/tsconfig.build.json +20 -0
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * A3M Router - Semantic Cache
4
+ *
5
+ * Stores previous query->response pairs and returns cached responses
6
+ * for semantically similar queries using character n-gram Jaccard similarity.
7
+ *
8
+ * No external embedding API needed. Trigram overlap catches paraphrases like:
9
+ * "What is Python?" ā‰ˆ "Tell me about Python" ā‰ˆ "Explain Python"
10
+ * "Write a sort fn" ā‰ˆ "Create a sorting fn" ā‰ˆ "How to sort an array"
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.SemanticCache = void 0;
14
+ // ============================================================
15
+ // N-gram utilities
16
+ // ============================================================
17
+ /**
18
+ * Normalize text: lowercase, collapse whitespace, strip punctuation edges.
19
+ */
20
+ function normalize(text) {
21
+ return text
22
+ .toLowerCase()
23
+ .replace(/\s+/g, " ")
24
+ .trim();
25
+ }
26
+ /**
27
+ * Extract character trigrams from text.
28
+ * Pads with spaces so short words still produce trigrams.
29
+ */
30
+ function extractTrigrams(text) {
31
+ const normalized = " " + normalize(text) + " ";
32
+ const trigrams = new Set();
33
+ for (let i = 0; i <= normalized.length - 3; i++) {
34
+ trigrams.add(normalized.substring(i, i + 3));
35
+ }
36
+ return trigrams;
37
+ }
38
+ /**
39
+ * Compute Jaccard similarity between two sets.
40
+ * |A ∩ B| / |A ∪ B|
41
+ */
42
+ function jaccard(a, b) {
43
+ if (a.size === 0 && b.size === 0)
44
+ return 1.0;
45
+ let intersection = 0;
46
+ for (const item of a) {
47
+ if (b.has(item))
48
+ intersection++;
49
+ }
50
+ const union = a.size + b.size - intersection;
51
+ return union === 0 ? 0 : intersection / union;
52
+ }
53
+ // ============================================================
54
+ // Semantic Cache
55
+ // ============================================================
56
+ class SemanticCache {
57
+ entries = [];
58
+ maxSize;
59
+ similarityThreshold;
60
+ ttl;
61
+ hits = 0;
62
+ misses = 0;
63
+ constructor(options) {
64
+ this.maxSize = options?.maxSize ?? 1000;
65
+ this.similarityThreshold = options?.similarityThreshold ?? 0.92;
66
+ this.ttl = options?.ttl ?? 3600000; // 1 hour
67
+ }
68
+ /**
69
+ * Get cached response for a semantically similar query.
70
+ * Returns the best match above the similarity threshold, or null.
71
+ */
72
+ async get(query) {
73
+ const now = Date.now();
74
+ const queryTrigrams = extractTrigrams(query);
75
+ let bestEntry = null;
76
+ let bestScore = 0;
77
+ for (const entry of this.entries) {
78
+ // Skip expired
79
+ if (now > entry.expiresAt)
80
+ continue;
81
+ const score = jaccard(queryTrigrams, entry.trigrams);
82
+ if (score > bestScore) {
83
+ bestScore = score;
84
+ bestEntry = entry;
85
+ }
86
+ }
87
+ if (bestEntry && bestScore >= this.similarityThreshold) {
88
+ this.hits++;
89
+ bestEntry.hitCount++;
90
+ return {
91
+ query: bestEntry.query,
92
+ response: bestEntry.response,
93
+ metadata: bestEntry.metadata,
94
+ cachedAt: bestEntry.cachedAt,
95
+ hitCount: bestEntry.hitCount,
96
+ };
97
+ }
98
+ this.misses++;
99
+ return null;
100
+ }
101
+ /**
102
+ * Store a query->response pair in the cache.
103
+ */
104
+ async set(query, response, metadata) {
105
+ const now = Date.now();
106
+ // Evict expired entries first
107
+ this.evictExpired();
108
+ // Evict oldest if at capacity
109
+ if (this.entries.length >= this.maxSize) {
110
+ this.evictOldest();
111
+ }
112
+ // Check if an exact-match entry already exists and update it
113
+ const normalized = normalize(query);
114
+ const existing = this.entries.find((e) => normalize(e.query) === normalized && now <= e.expiresAt);
115
+ if (existing) {
116
+ existing.response = response;
117
+ existing.metadata = metadata;
118
+ existing.cachedAt = now;
119
+ existing.expiresAt = now + this.ttl;
120
+ existing.trigrams = extractTrigrams(query);
121
+ return;
122
+ }
123
+ this.entries.push({
124
+ query,
125
+ response,
126
+ metadata,
127
+ cachedAt: now,
128
+ expiresAt: now + this.ttl,
129
+ hitCount: 0,
130
+ trigrams: extractTrigrams(query),
131
+ });
132
+ }
133
+ /**
134
+ * Clear all cache entries.
135
+ */
136
+ clear() {
137
+ this.entries = [];
138
+ }
139
+ /**
140
+ * Get cache statistics.
141
+ */
142
+ getStats() {
143
+ const total = this.hits + this.misses;
144
+ return {
145
+ hits: this.hits,
146
+ misses: this.misses,
147
+ hitRate: total > 0 ? this.hits / total : 0,
148
+ size: this.entries.length,
149
+ };
150
+ }
151
+ /**
152
+ * Purge expired entries.
153
+ */
154
+ evictExpired() {
155
+ const now = Date.now();
156
+ this.entries = this.entries.filter((e) => now <= e.expiresAt);
157
+ }
158
+ /**
159
+ * Evict the oldest (by cachedAt) entry.
160
+ */
161
+ evictOldest() {
162
+ if (this.entries.length === 0)
163
+ return;
164
+ let oldestIdx = 0;
165
+ let oldestTime = Infinity;
166
+ for (let i = 0; i < this.entries.length; i++) {
167
+ if (this.entries[i].cachedAt < oldestTime) {
168
+ oldestTime = this.entries[i].cachedAt;
169
+ oldestIdx = i;
170
+ }
171
+ }
172
+ this.entries.splice(oldestIdx, 1);
173
+ }
174
+ }
175
+ exports.SemanticCache = SemanticCache;
176
+ //# sourceMappingURL=semanticCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semanticCache.js","sourceRoot":"","sources":["../../src/cache/semanticCache.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAgCH,+DAA+D;AAC/D,mBAAmB;AACnB,+DAA+D;AAE/D;;GAEG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,UAAU,GAAG,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,CAAc,EAAE,CAAc;IAC7C,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAC7C,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,YAAY,EAAE,CAAC;IAClC,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,YAAY,CAAC;IAC7C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC;AAChD,CAAC;AAED,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAE/D,MAAa,aAAa;IAChB,OAAO,GAAiB,EAAE,CAAC;IAC3B,OAAO,CAAS;IAChB,mBAAmB,CAAS;IAC5B,GAAG,CAAS;IACZ,IAAI,GAAG,CAAC,CAAC;IACT,MAAM,GAAG,CAAC,CAAC;IAEnB,YAAY,OAA8B;QACxC,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,mBAAmB,GAAG,OAAO,EAAE,mBAAmB,IAAI,IAAI,CAAC;QAChE,IAAI,CAAC,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC,SAAS;IAC/C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAG,CAAC,KAAa;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,aAAa,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAE7C,IAAI,SAAS,GAAsB,IAAI,CAAC;QACxC,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,eAAe;YACf,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS;gBAAE,SAAS;YAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;YACrD,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;gBACtB,SAAS,GAAG,KAAK,CAAC;gBAClB,SAAS,GAAG,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;QAED,IAAI,SAAS,IAAI,SAAS,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,SAAS,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO;gBACL,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,QAAQ,EAAE,SAAS,CAAC,QAAQ;aAC7B,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,KAAa,EAAE,QAAgB,EAAE,QAAc;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,8BAA8B;QAC9B,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,8BAA8B;QAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;QAED,6DAA6D;QAC7D,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,UAAU,IAAI,GAAG,IAAI,CAAC,CAAC,SAAS,CAC/D,CAAC;QACF,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC7B,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC7B,QAAQ,CAAC,QAAQ,GAAG,GAAG,CAAC;YACxB,QAAQ,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;YACpC,QAAQ,CAAC,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,KAAK;YACL,QAAQ;YACR,QAAQ;YACR,QAAQ,EAAE,GAAG;YACb,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG;YACzB,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;QACtC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;SAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,YAAY;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACK,WAAW;QACjB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACtC,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,UAAU,GAAG,QAAQ,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,UAAU,EAAE,CAAC;gBAC1C,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACtC,SAAS,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACpC,CAAC;CACF;AAtID,sCAsIC"}
package/dist/cli.js CHANGED
@@ -3,6 +3,7 @@
3
3
  * A3M Router CLI - Adaptive Memory Multi-Model Router
4
4
  *
5
5
  * Commands:
6
+ * npx a3m-router serve [--port 8787] Start OpenAI-compatible proxy server
6
7
  * npx a3m-router route <query> Route query to best provider
7
8
  * npx a3m-router batch <q1> <q2>.. Route multiple queries
8
9
  * npx a3m-router providers List all configured providers
@@ -24,6 +25,13 @@ const {
24
25
  getAvailableProviders, providerConfig, registerProvider, loadProviders,
25
26
  } = require('./index.js');
26
27
 
28
+ let createProxyServer;
29
+ try {
30
+ createProxyServer = require('./server/proxyServer.js').createProxyServer;
31
+ } catch (e) {
32
+ // Server module not yet compiled
33
+ }
34
+
27
35
  const args = process.argv.slice(2);
28
36
  const command = args[0];
29
37
 
@@ -394,11 +402,36 @@ async function main() {
394
402
  break;
395
403
  }
396
404
 
405
+ case 'serve': {
406
+ if (!createProxyServer) {
407
+ console.error('\n Error: Server module not available.');
408
+ console.error(' Build first: npm run build');
409
+ console.error(' Or use directly: node -e "require(\'./server/proxyServer.js\').createProxyServer()"\n');
410
+ process.exit(1);
411
+ }
412
+
413
+ // Parse --port argument
414
+ var portArg = args.indexOf('--port');
415
+ var port = undefined;
416
+ if (portArg !== -1 && args[portArg + 1]) {
417
+ port = parseInt(args[portArg + 1], 10);
418
+ if (isNaN(port)) {
419
+ console.error(' Error: --port must be a number');
420
+ process.exit(1);
421
+ }
422
+ }
423
+
424
+ console.log('\n Starting A3M Router Proxy Server...');
425
+ createProxyServer(port);
426
+ break;
427
+ }
428
+
397
429
  default:
398
430
  console.log('\nšŸ”€ A3M Router — Adaptive Memory Multi-Model Router');
399
431
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
400
432
  console.log('');
401
433
  console.log(' Commands:');
434
+ console.log(' serve [--port 8787] Start OpenAI-compatible proxy server');
402
435
  console.log(' route <query> Route query to best provider');
403
436
  console.log(' batch <q1> <q2>.. Route multiple queries');
404
437
  console.log(' compare <query> Compare providers side by side');
@@ -420,6 +453,8 @@ async function main() {
420
453
  console.log(' Env: GROQ_API_KEY, CEREBRAS_API_KEY, MISTRAL_API_KEY, etc.');
421
454
  console.log('');
422
455
  console.log(' Examples:');
456
+ console.log(' npx a3m-router serve # Start proxy on :8787');
457
+ console.log(' npx a3m-router serve --port 3000 # Start proxy on :3000');
423
458
  console.log(' npx a3m-router route "Write a Python function to sort"');
424
459
  console.log(' npx a3m-router compare "What is 2+2?"');
425
460
  console.log(' npx a3m-router providers');