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,182 @@
1
+ /**
2
+ * A3M Router - Model Mapper
3
+ *
4
+ * Maps OpenAI-compatible model names to our provider/model pairs.
5
+ * Supports:
6
+ * - "auto" → intelligent routing via advancedRouter
7
+ * - "gpt-4" → best available premium provider
8
+ * - "gpt-3.5-turbo" → best available fast provider
9
+ * - "groq/llama-3.3-70b" → specific provider/model
10
+ * - "claude-3.5-sonnet" → Anthropic provider
11
+ * - "gemini-2.0-flash" → Google provider
12
+ */
13
+
14
+ import { routeQuery } from "../routing/advancedRouter";
15
+ import { getAvailableProviders } from "../providers/providerConfig";
16
+
17
+ // ============================================================
18
+ // TYPE DEFINITIONS
19
+ // ============================================================
20
+
21
+ export interface ModelMapping {
22
+ providerId: string;
23
+ model: string;
24
+ baseUrl: string;
25
+ apiKey: string | null;
26
+ costPerK: { input: number; output: number };
27
+ type: string;
28
+ }
29
+
30
+ // ============================================================
31
+ // OPENAI MODEL ALIASES → provider preference order
32
+ // ============================================================
33
+
34
+ const OPENAI_ALIASES: Record<string, string[]> = {
35
+ "gpt-4": ["openai/gpt-4o", "anthropic/claude-3.5-sonnet", "google/gemini-2.5-pro", "mistral/mistral-large-latest"],
36
+ "gpt-4-turbo": ["openai/gpt-4-turbo", "openai/gpt-4o", "anthropic/claude-3.5-sonnet"],
37
+ "gpt-4o": ["openai/gpt-4o", "anthropic/claude-3.5-sonnet", "google/gemini-2.5-pro"],
38
+ "gpt-4o-mini": ["openai/gpt-4o-mini", "groq/llama-3.3-70b-versatile", "google/gemini-2.0-flash", "mistral/mistral-small-latest"],
39
+ "gpt-3.5-turbo": ["groq/llama-3.3-70b-versatile", "cerebras/llama3.1-8b", "google/gemini-2.0-flash", "mistral/mistral-small-latest", "deepseek/deepseek-chat"],
40
+ "claude-3.5-sonnet": ["anthropic/claude-3.5-sonnet"],
41
+ "claude-3-opus": ["anthropic/claude-3-opus"],
42
+ "claude-3-haiku": ["anthropic/claude-3-haiku"],
43
+ "gemini-2.0-flash": ["google/gemini-2.0-flash"],
44
+ "gemini-2.5-pro": ["google/gemini-2.5-pro"],
45
+ "o1": ["openai/gpt-4o", "anthropic/claude-3.5-sonnet"],
46
+ "o1-mini": ["openai/gpt-4o-mini", "groq/llama-3.3-70b-versatile"],
47
+ "o3-mini": ["openai/gpt-4o-mini", "google/gemini-2.5-flash"],
48
+ };
49
+
50
+ // ============================================================
51
+ // MODEL MAPPING
52
+ // ============================================================
53
+
54
+ /**
55
+ * Resolve an OpenAI-compatible model name to a concrete provider/model pair.
56
+ *
57
+ * Resolution order:
58
+ * 1. "auto" → route through advancedRouter
59
+ * 2. "provider/model" format → direct lookup
60
+ * 3. OpenAI alias → preference list lookup
61
+ * 4. Bare model name → search across all providers
62
+ * 5. Fallback → first available provider's first model
63
+ */
64
+ export function resolveModel(modelName: string, prompt?: string): ModelMapping | null {
65
+ const available = getAvailableProviders();
66
+
67
+ // 1. "auto" → intelligent routing
68
+ if (modelName === "auto") {
69
+ const query = prompt || "";
70
+ const route = routeQuery(query);
71
+ if (!route.primary_model) return null;
72
+ return lookupProviderModel(route.primary_model, available);
73
+ }
74
+
75
+ // 2. "provider/model" format → direct lookup
76
+ if (modelName.includes("/")) {
77
+ const mapping = lookupProviderModel(modelName, available);
78
+ if (mapping) return mapping;
79
+ }
80
+
81
+ // 3. OpenAI alias → preference list
82
+ const aliasList = OPENAI_ALIASES[modelName];
83
+ if (aliasList) {
84
+ for (const candidate of aliasList) {
85
+ const mapping = lookupProviderModel(candidate, available);
86
+ if (mapping) return mapping;
87
+ }
88
+ }
89
+
90
+ // 4. Bare model name → search across all providers
91
+ for (const [providerId, provider] of Object.entries(available)) {
92
+ if (provider.models && provider.models.includes(modelName)) {
93
+ return {
94
+ providerId,
95
+ model: modelName,
96
+ baseUrl: provider.baseUrl || "",
97
+ apiKey: provider.apiKey || null,
98
+ costPerK: provider.costPerK || { input: 0, output: 0 },
99
+ type: provider.type || "api",
100
+ };
101
+ }
102
+ }
103
+
104
+ // 5. Fallback → first available provider's first model
105
+ const firstProvider = Object.values(available)[0] as any;
106
+ if (firstProvider && firstProvider.models && firstProvider.models.length > 0) {
107
+ return {
108
+ providerId: firstProvider.id,
109
+ model: firstProvider.models[0],
110
+ baseUrl: firstProvider.baseUrl || "",
111
+ apiKey: firstProvider.apiKey || null,
112
+ costPerK: firstProvider.costPerK || { input: 0, output: 0 },
113
+ type: firstProvider.type || "api",
114
+ };
115
+ }
116
+
117
+ return null;
118
+ }
119
+
120
+ /**
121
+ * Look up a "provider/model" key against the available providers map.
122
+ */
123
+ function lookupProviderModel(key: string, available: Record<string, any>): ModelMapping | null {
124
+ const slashIdx = key.indexOf("/");
125
+ const providerId = slashIdx >= 0 ? key.substring(0, slashIdx) : key;
126
+ const model = slashIdx >= 0 ? key.substring(slashIdx + 1) : key;
127
+
128
+ const provider = available[providerId];
129
+ if (!provider) return null;
130
+
131
+ // Verify the model is in the provider's list (or accept if list is empty)
132
+ if (provider.models && provider.models.length > 0 && !provider.models.includes(model)) {
133
+ return null;
134
+ }
135
+
136
+ return {
137
+ providerId,
138
+ model,
139
+ baseUrl: provider.baseUrl || "",
140
+ apiKey: provider.apiKey || null,
141
+ costPerK: provider.costPerK || { input: 0, output: 0 },
142
+ type: provider.type || "api",
143
+ };
144
+ }
145
+
146
+ /**
147
+ * List all available models in OpenAI-compatible format.
148
+ */
149
+ export function listAvailableModels(): Array<{
150
+ id: string;
151
+ object: string;
152
+ created: number;
153
+ owned_by: string;
154
+ }> {
155
+ const available = getAvailableProviders();
156
+ const models: Array<{ id: string; object: string; created: number; owned_by: string }> = [];
157
+
158
+ for (const [providerId, provider] of Object.entries(available)) {
159
+ if (provider.models) {
160
+ for (const model of provider.models) {
161
+ models.push({
162
+ id: providerId + "/" + model,
163
+ object: "model",
164
+ created: Math.floor(Date.now() / 1000),
165
+ owned_by: provider.name || providerId,
166
+ });
167
+ }
168
+ }
169
+ }
170
+
171
+ // Add aliases
172
+ for (const alias of Object.keys(OPENAI_ALIASES)) {
173
+ models.push({
174
+ id: alias,
175
+ object: "model",
176
+ created: Math.floor(Date.now() / 1000),
177
+ owned_by: "a3m-router",
178
+ });
179
+ }
180
+
181
+ return models;
182
+ }