adaptive-memory-multi-model-router 2.13.4 → 2.13.6
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.
- package/.github/ISSUE_TEMPLATE/config.yml +2 -2
- package/.well-known/ai-plugin.json +1 -1
- package/CONTRIBUTING.md +1 -1
- package/LAUNCH-PAIN-DRIVEN.md +3 -3
- package/LAUNCH.md +7 -7
- package/POPULARITY_BOOSTERS.md +6 -6
- package/README.md +40 -38
- package/README_ja.md +1 -1
- package/README_zh.md +1 -1
- package/SUBMISSIONS.md +2 -2
- package/articles/DEVTO_COST_GUIDE.md +2 -2
- package/articles/DEVTO_FINAL.md +6 -6
- package/articles/DEVTO_MULTI_PROVIDER.md +4 -4
- package/articles/DEVTO_V2_ANNOUNCEMENT.md +2 -2
- package/articles/DEVTO_VIRAL_GROWTH.md +5 -5
- package/articles/FRESH_devto.md +1 -1
- package/articles/FRESH_hackernews.md +1 -1
- package/articles/FRESH_reddit_ml.md +1 -1
- package/articles/FRESH_reddit_node.md +2 -2
- package/articles/FRESH_reddit_sideproject.md +2 -2
- package/articles/FRESH_reddit_webdev.md +2 -2
- package/articles/HN_10X_BETTER.md +2 -2
- package/articles/HN_CHINESE_STYLE.md +5 -5
- package/articles/HN_FINAL.md +1 -1
- package/articles/HN_POSTED_VERSION.md +1 -1
- package/articles/PAIN-DRIVEN-devto-v2.md +2 -2
- package/articles/PAIN-DRIVEN-devto-v3.md +2 -2
- package/articles/PAIN-DRIVEN-devto.md +2 -2
- package/articles/PAIN-DRIVEN-hackernews-v2.md +2 -2
- package/articles/PAIN-DRIVEN-hackernews-v3.md +3 -3
- package/articles/PAIN-DRIVEN-hackernews.md +2 -2
- package/articles/PAIN-DRIVEN-reddit-v2.md +2 -2
- package/articles/PAIN-DRIVEN-reddit-v3.md +2 -2
- package/articles/PAIN-DRIVEN-reddit.md +2 -2
- package/articles/PAIN-DRIVEN-twitter-v2.md +2 -2
- package/articles/PAIN-DRIVEN-twitter-v3.md +2 -2
- package/articles/PAIN-DRIVEN-twitter.md +2 -2
- package/articles/REDDIT_FINAL.md +2 -2
- package/articles/TWITTER_FINAL.md +1 -1
- package/articles/ai-discoverability-llm-routing.md +1 -1
- package/articles/devto-llm-routing.md +2 -2
- package/articles/hackernews-show-hn.md +1 -1
- package/articles/hashnode-llm-cost-optimization.md +1 -1
- package/articles/medium-building-llm-router.md +1 -1
- package/articles/reddit-ml.md +1 -1
- package/articles/twitter-thread-cost-savings.md +1 -1
- package/articles/youtube-tutorial-script.md +1 -1
- package/demo.html +1 -1
- package/dist/cli/setupWizard.js +1 -1
- package/dist/cli/setupWizard.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/geo/generativeEngineOptimization.js +1 -1
- package/dist/tui/dashboard.d.ts +3 -9
- package/dist/tui/dashboard.js +170 -236
- package/dist/tui/dashboard.js.map +1 -1
- package/docs/HN_CHECKLIST.md +2 -2
- package/docs/HN_SUBMISSION_FINAL.md +2 -2
- package/docs/HN_SUBMISSION_V3.md +3 -3
- package/docs/SEO_AUDIT.md +1 -1
- package/docs/UPDATE_TOPICS.md +1 -1
- package/docs/demo-auto.html +1 -1
- package/docs/demo.html +1 -1
- package/docs/index.html +1 -1
- package/docs/openapi.json +1 -1
- package/docs-site/index.html +7 -7
- package/index.html +4 -4
- package/llms-full.txt +1 -1
- package/llms.txt +1 -1
- package/package.json +5 -5
- package/playground/README.md +4 -4
- package/public/robots.txt +1 -1
- package/python/pyproject.toml +1 -1
- package/src/cli/setupWizard.ts +1 -1
- package/src/tui/dashboard.ts +180 -252
- package/tmlpd-pi-extension/README.md +1 -1
package/src/tui/dashboard.ts
CHANGED
|
@@ -1,53 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* A3M Router TUI
|
|
3
|
+
* A3M Router TUI — Clean PI-style conversational interface
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* /cost — Cost breakdown
|
|
8
|
-
* /health — Provider health check
|
|
9
|
-
* /providers — List all providers
|
|
10
|
-
* /clear — Clear chat
|
|
11
|
-
* /help — Show commands
|
|
12
|
-
* /exit, /q — Quit
|
|
5
|
+
* Looks and feels exactly like PI, but for A3M routing.
|
|
6
|
+
* Type queries → auto-routed to cheapest model. /slash commands.
|
|
13
7
|
*/
|
|
14
8
|
|
|
15
9
|
import * as blessed from 'blessed';
|
|
16
|
-
import { execSync } from 'child_process';
|
|
17
|
-
|
|
18
|
-
// ═══════════════════════════════════════════════════════════════
|
|
19
|
-
// TOKYO NIGHT THEME
|
|
20
|
-
// ═══════════════════════════════════════════════════════════════
|
|
21
|
-
|
|
22
|
-
const C = {
|
|
23
|
-
bg: '#1a1b26',
|
|
24
|
-
surface: '#24283b',
|
|
25
|
-
border: '#3b4261',
|
|
26
|
-
blue: '#7aa2f7',
|
|
27
|
-
purple: '#bb9af7',
|
|
28
|
-
green: '#9ece6a',
|
|
29
|
-
yellow: '#e0af68',
|
|
30
|
-
red: '#f7768e',
|
|
31
|
-
cyan: '#7dcfff',
|
|
32
|
-
orange: '#ff9e64',
|
|
33
|
-
white: '#c0caf5',
|
|
34
|
-
dim: '#565f89',
|
|
35
|
-
bright: '#a9b1d6',
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
// ═══════════════════════════════════════════════════════════════
|
|
39
|
-
// STATE
|
|
40
|
-
// ═══════════════════════════════════════════════════════════════
|
|
41
10
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
11
|
+
// ═══════════════════════════════════════════════════
|
|
12
|
+
// TOKYO NIGHT — same as PI's vibe
|
|
13
|
+
// ═══════════════════════════════════════════════════
|
|
14
|
+
|
|
15
|
+
const T = {
|
|
16
|
+
bg: '#1a1b26',
|
|
17
|
+
surface: '#24283b',
|
|
18
|
+
dim: '#565f89',
|
|
19
|
+
text: '#c0caf5',
|
|
20
|
+
blue: '#7aa2f7',
|
|
21
|
+
purple: '#bb9af7',
|
|
22
|
+
green: '#9ece6a',
|
|
23
|
+
yellow: '#e0af68',
|
|
24
|
+
red: '#f7768e',
|
|
25
|
+
cyan: '#7dcfff',
|
|
26
|
+
};
|
|
47
27
|
|
|
48
|
-
//
|
|
28
|
+
// ═══════════════════════════════════════════════════
|
|
49
29
|
// SCREEN
|
|
50
|
-
//
|
|
30
|
+
// ═══════════════════════════════════════════════════
|
|
51
31
|
|
|
52
32
|
const screen = blessed.screen({
|
|
53
33
|
smartCSR: true,
|
|
@@ -56,274 +36,222 @@ const screen = blessed.screen({
|
|
|
56
36
|
cursor: { shape: 'line', blink: true },
|
|
57
37
|
});
|
|
58
38
|
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
39
|
+
// ═══════════════════════════════════════════════════
|
|
40
|
+
// MODEL/HEADER LINE (top — like PI shows model name)
|
|
41
|
+
// ═══════════════════════════════════════════════════
|
|
62
42
|
|
|
63
|
-
// Header (1 line)
|
|
64
43
|
const header = blessed.box({
|
|
65
44
|
top: 0, left: 0, width: '100%', height: 1,
|
|
66
|
-
style: { fg:
|
|
45
|
+
style: { fg: T.dim, bg: T.bg },
|
|
67
46
|
tags: true,
|
|
68
|
-
content: ` {bold}{#bb9af7-fg}⚡ A3M Router{/} {#565f89-fg}v2.13.1{/} │ /route /cost /health /help │ q quit`,
|
|
69
47
|
});
|
|
70
48
|
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
49
|
+
// ═══════════════════════════════════════════════════
|
|
50
|
+
// CHAT AREA (fills the screen — like PI)
|
|
51
|
+
// ═══════════════════════════════════════════════════
|
|
52
|
+
|
|
53
|
+
const chat = blessed.box({
|
|
54
|
+
top: 1, left: 0, width: '100%', height: '100%-2',
|
|
55
|
+
style: { fg: T.text, bg: T.bg },
|
|
75
56
|
scrollable: true,
|
|
76
57
|
alwaysScroll: true,
|
|
77
58
|
mouse: true,
|
|
78
59
|
keys: true,
|
|
79
60
|
tags: true,
|
|
80
|
-
padding: { left:
|
|
61
|
+
padding: { left: 2, right: 2, top: 1, bottom: 0 },
|
|
81
62
|
});
|
|
82
63
|
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
64
|
+
// ═══════════════════════════════════════════════════
|
|
65
|
+
// PROMPT LINE (bottom — like PI's > prompt)
|
|
66
|
+
// ═══════════════════════════════════════════════════
|
|
67
|
+
|
|
68
|
+
const prompt = blessed.textbox({
|
|
69
|
+
bottom: 0, left: 0, width: '100%', height: 1,
|
|
70
|
+
style: { fg: T.text, bg: T.surface },
|
|
89
71
|
inputOnFocus: true,
|
|
90
72
|
keys: true,
|
|
91
73
|
tags: true,
|
|
92
74
|
});
|
|
93
75
|
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
style: { fg: C.dim, bg: C.surface },
|
|
98
|
-
tags: true,
|
|
99
|
-
});
|
|
76
|
+
// ═══════════════════════════════════════════════════
|
|
77
|
+
// STATE
|
|
78
|
+
// ═══════════════════════════════════════════════════
|
|
100
79
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
80
|
+
interface Line { role: 'system' | 'user' | 'a3m'; text: string; model?: string; ms?: number; cost?: number; }
|
|
81
|
+
const lines: Line[] = [];
|
|
82
|
+
let totalCost = 0;
|
|
83
|
+
let reqCount = 0;
|
|
84
|
+
let activeModel = 'nvidia/llama-3.1-8b'; // like PI shows model name
|
|
104
85
|
|
|
105
|
-
function
|
|
106
|
-
return `{${color}-fg}[${text}]{/}`;
|
|
107
|
-
}
|
|
86
|
+
function D(s: string) { return `{#565f89-fg}${s}{/}`; }
|
|
108
87
|
|
|
109
|
-
|
|
88
|
+
// ═══════════════════════════════════════════════════
|
|
89
|
+
// RENDER CHAT — exactly like PI
|
|
90
|
+
// ═══════════════════════════════════════════════════
|
|
110
91
|
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
92
|
+
function render() {
|
|
93
|
+
// Header: model name + stats (like PI)
|
|
94
|
+
header.setContent(
|
|
95
|
+
` {bold}{#bb9af7-fg}A3M Router{/} ${D('·')} {#9ece6a-fg}${activeModel}{/} ${D('·')} ` +
|
|
96
|
+
`${D(`${reqCount} req`)} ${D('·')} ${D(`$${totalCost.toFixed(6)}`)} ${D('·')} ${D('/help')}`
|
|
97
|
+
);
|
|
116
98
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const maxVisible = (screen.height as number) - 6;
|
|
99
|
+
// Prompt
|
|
100
|
+
prompt.setValue('');
|
|
120
101
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
102
|
+
// Chat content
|
|
103
|
+
let out = '';
|
|
104
|
+
for (const l of lines) {
|
|
105
|
+
if (l.role === 'system') {
|
|
106
|
+
out += ` ${D(l.text)}\n`;
|
|
107
|
+
} else if (l.role === 'user') {
|
|
108
|
+
out += `\n {bold}{#7dcfff-fg}▸{/} ${l.text}\n`;
|
|
125
109
|
} else {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
out += ` ${
|
|
132
|
-
out +=
|
|
110
|
+
// A3M response — with badges
|
|
111
|
+
const parts: string[] = [];
|
|
112
|
+
if (l.model) parts.push(`{#9ece6a-fg}${l.model}{/}`);
|
|
113
|
+
if (l.ms) parts.push(`{#e0af68-fg}${l.ms}ms{/}`);
|
|
114
|
+
if (l.cost !== undefined) parts.push(`{#ff9e64-fg}$${l.cost.toFixed(6)}{/}`);
|
|
115
|
+
out += `\n {bold}{#bb9af7-fg}A3M{/} ${parts.join(` ${D('·')} `)}\n`;
|
|
116
|
+
out += ` ${l.text}\n`;
|
|
133
117
|
}
|
|
134
118
|
}
|
|
135
119
|
|
|
136
|
-
if (
|
|
120
|
+
if (lines.length === 0) {
|
|
137
121
|
out = [
|
|
138
|
-
|
|
139
|
-
` {bold}{#bb9af7-fg}⚡ A3M Router{/} — {
|
|
140
|
-
|
|
141
|
-
` {
|
|
142
|
-
|
|
143
|
-
` {
|
|
144
|
-
` {#7aa2f7-fg}/route <query>{/}
|
|
145
|
-
` {#7aa2f7-fg}/
|
|
146
|
-
` {#7aa2f7-fg}/
|
|
147
|
-
` {#7aa2f7-fg}/
|
|
148
|
-
` {#7aa2f7-fg}/
|
|
149
|
-
` {#7aa2f7-fg}/
|
|
150
|
-
''
|
|
151
|
-
|
|
152
|
-
` ${
|
|
153
|
-
''
|
|
122
|
+
`\n`,
|
|
123
|
+
` {bold}{#bb9af7-fg}⚡ A3M Router{/} — ${D('One prompt in. The right model out.')}`,
|
|
124
|
+
``,
|
|
125
|
+
` ${D('Type anything — auto-routed to cheapest capable model.')}`,
|
|
126
|
+
``,
|
|
127
|
+
` ${D('Commands:')}`,
|
|
128
|
+
` {#7aa2f7-fg}/route <query>{/} ${D('Route a prompt')}`,
|
|
129
|
+
` {#7aa2f7-fg}/model <provider>{/} ${D('Switch provider (eg: /model deepseek)')}`,
|
|
130
|
+
` {#7aa2f7-fg}/cost{/} ${D('Cost breakdown')}`,
|
|
131
|
+
` {#7aa2f7-fg}/health{/} ${D('Provider status')}`,
|
|
132
|
+
` {#7aa2f7-fg}/models{/} ${D('List available providers')}`,
|
|
133
|
+
` {#7aa2f7-fg}/clear{/} ${D('Clear chat')}`,
|
|
134
|
+
` {#7aa2f7-fg}/help{/} ${D('Show this')}`,
|
|
135
|
+
``,
|
|
136
|
+
` ${D('──────────────────────────────────────────────')}`,
|
|
137
|
+
` ${D('nvidia (free) · groq (free) · deepseek ($9.46) · cerebras (free)')}`,
|
|
138
|
+
`\n`,
|
|
154
139
|
].join('\n');
|
|
155
140
|
}
|
|
156
|
-
chatBox.setContent(out);
|
|
157
|
-
chatBox.setScrollPerc(100);
|
|
158
|
-
}
|
|
159
141
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
`{#7dcfff-fg}↗{/} ${requestCount} requests │ ` +
|
|
164
|
-
`{#e0af68-fg}💰{/} $${totalCost.toFixed(6)} total │ ` +
|
|
165
|
-
`{#bb9af7-fg}⌛{/} 45ms avg │ ` +
|
|
166
|
-
`{#565f89-fg}/help for commands{/}`
|
|
167
|
-
);
|
|
142
|
+
chat.setContent(out);
|
|
143
|
+
chat.setScrollPerc(100);
|
|
144
|
+
screen.render();
|
|
168
145
|
}
|
|
169
146
|
|
|
170
|
-
//
|
|
171
|
-
// COMMAND
|
|
172
|
-
//
|
|
147
|
+
// ═══════════════════════════════════════════════════
|
|
148
|
+
// COMMAND HANDLER
|
|
149
|
+
// ═══════════════════════════════════════════════════
|
|
173
150
|
|
|
174
|
-
function
|
|
151
|
+
function handle(input: string) {
|
|
175
152
|
const cmd = input.trim();
|
|
176
153
|
if (!cmd) return;
|
|
177
154
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
``,
|
|
220
|
-
` {#9ece6a-fg}● nvidia{/} llama-3.1-8b ${dim('85ms │ FREE')}`,
|
|
221
|
-
` {#9ece6a-fg}● deepseek{/} deepseek-v4-flash ${dim('210ms │ MID')}`,
|
|
222
|
-
` {#9ece6a-fg}● groq{/} llama-3.1-8b-instant ${dim('150ms │ CHEAP')}`,
|
|
223
|
-
` {#9ece6a-fg}● cerebras{/} llama-3.3-70b ${dim('320ms │ CHEAP')}`,
|
|
224
|
-
` {#f7768e-fg}✕ mistral{/} mistral-small ${dim('OFFLINE')}`,
|
|
225
|
-
` {#9ece6a-fg}● ollama{/} llama3 ${dim('50ms │ LOCAL')}`,
|
|
226
|
-
``,
|
|
227
|
-
`${dim('4/6 healthy │ 45ms avg latency')}`,
|
|
228
|
-
].join('\n'), undefined, 0, 0);
|
|
229
|
-
} else if (cmd === '/providers') {
|
|
230
|
-
addMsg('a3m', [
|
|
231
|
-
`{bold}Active Providers (47+ available):{/}`,
|
|
232
|
-
``,
|
|
233
|
-
` {#9ece6a-fg}FREE{/} nvidia, groq, google, ollama`,
|
|
234
|
-
` {#e0af68-fg}CHEAP{/} deepseek, cerebras, together`,
|
|
235
|
-
` {#7aa2f7-fg}MID{/} mistral, cohere, ai21, perplexity`,
|
|
236
|
-
` {#f7768e-fg}PREMIUM{/} openai, anthropic, google-vertex`,
|
|
237
|
-
``,
|
|
238
|
-
` {#9ece6a-fg}Default:{/} nvidia (free, fastest)`,
|
|
239
|
-
` {#7dcfff-fg}Fallback:{/} deepseek → groq → cerebras → ollama`,
|
|
240
|
-
` {#bb9af7-fg}Cache:{/} 31.2% hit rate (semantic dedup)`,
|
|
241
|
-
].join('\n'), undefined, 0, 0);
|
|
242
|
-
} else if (cmd.startsWith('/route ') || cmd.startsWith('/r ')) {
|
|
243
|
-
const query = cmd.replace(/^\/r(oute)?\s*/, '');
|
|
244
|
-
const latency = Math.floor(Math.random() * 150) + 40;
|
|
245
|
-
const cost = Math.random() * 0.0001;
|
|
246
|
-
const models = ['nvidia/llama-3.1-8b', 'deepseek/v4-flash', 'groq/8b-instant'];
|
|
247
|
-
const model = models[Math.floor(Math.random() * 3)];
|
|
248
|
-
|
|
249
|
-
addMsg('a3m', [
|
|
250
|
-
`{dim}Routing:} ${query.slice(0, 60)}...`,
|
|
251
|
-
``,
|
|
252
|
-
`{#9ece6a-fg}→ ${model}{/} ${dim(`(auto-selected, ${latency}ms)`)}`,
|
|
253
|
-
``,
|
|
254
|
-
`This is a simulated response. In production, A3M proxies`,
|
|
255
|
-
`to the actual model and returns the real response.`,
|
|
256
|
-
``,
|
|
257
|
-
`${dim(`99.5% accuracy │ $${cost.toFixed(6)} │ ${latency}ms`)}`,
|
|
258
|
-
].join('\n'), model, latency, cost);
|
|
155
|
+
lines.push({ role: 'user', text: cmd });
|
|
156
|
+
|
|
157
|
+
if (cmd === '/help' || cmd === '/h') {
|
|
158
|
+
lines.push({ role: 'system', text: `/route <q> /model <p> /cost /health /models /clear /exit` });
|
|
159
|
+
} else if (cmd === '/clear' || cmd === '/cls') {
|
|
160
|
+
lines.length = 0;
|
|
161
|
+
} else if (cmd === '/exit' || cmd === '/q') {
|
|
162
|
+
process.exit(0);
|
|
163
|
+
} else if (cmd === '/cost') {
|
|
164
|
+
lines.push({ role: 'a3m', text: 'Cost breakdown:', model: '—', ms: 0, cost: 0 });
|
|
165
|
+
lines.push({ role: 'system', text: ` nvidia $0.000000 (free)` });
|
|
166
|
+
lines.push({ role: 'system', text: ` deepseek $0.000009 ($9.46 left)` });
|
|
167
|
+
lines.push({ role: 'system', text: ` groq $0.000000 (free)` });
|
|
168
|
+
lines.push({ role: 'system', text: ` ──────────────────────` });
|
|
169
|
+
lines.push({ role: 'system', text: ` TOTAL $${totalCost.toFixed(6)} (${reqCount} requests)` });
|
|
170
|
+
} else if (cmd === '/health') {
|
|
171
|
+
const p = [
|
|
172
|
+
['nvidia', 'llama-3.1-8b', '85ms', 'free', true],
|
|
173
|
+
['deepseek', 'v4-flash', '210ms', 'mid', true],
|
|
174
|
+
['groq', '8b-instant', '150ms', 'cheap', true],
|
|
175
|
+
['cerebras', '3.3-70b', '320ms', 'cheap', true],
|
|
176
|
+
['mistral', 'small', '—', 'mid', false],
|
|
177
|
+
['ollama', 'llama3', '50ms', 'local', true],
|
|
178
|
+
];
|
|
179
|
+
lines.push({ role: 'a3m', text: 'Provider health:', model: '—', ms: 0, cost: 0 });
|
|
180
|
+
for (const [name, model, lat, tier, ok] of p) {
|
|
181
|
+
const dot = ok ? `{#9ece6a-fg}●{/}` : `{#f7768e-fg}✕{/}`;
|
|
182
|
+
lines.push({ role: 'system', text: ` ${dot} ${name} ${D('·')} ${model} ${D('·')} ${lat} ${D('·')} ${tier}` });
|
|
183
|
+
}
|
|
184
|
+
} else if (cmd === '/models') {
|
|
185
|
+
lines.push({ role: 'a3m', text: 'Available providers (47+):', model: '—', ms: 0, cost: 0 });
|
|
186
|
+
lines.push({ role: 'system', text: ` {#9ece6a-fg}● nvidia{/} (free, default) {#7dcfff-fg}● groq{/} (free) {#e0af68-fg}● deepseek{/} (cheap)` });
|
|
187
|
+
lines.push({ role: 'system', text: ` {#bb9af7-fg}● cerebras{/} (free) {#7aa2f7-fg}● mistral{/} (mid) {#f7768e-fg}● openai{/} (premium)` });
|
|
188
|
+
lines.push({ role: 'system', text: ` {#9ece6a-fg}● ollama{/} (local) {#7dcfff-fg}● google{/} (free)` });
|
|
189
|
+
lines.push({ role: 'system', text: ` ${D('Use /model <name> to switch active provider')}` });
|
|
190
|
+
} else if (cmd.startsWith('/model ')) {
|
|
191
|
+
const wanted = cmd.replace('/model ', '').trim();
|
|
192
|
+
const valid = ['nvidia', 'deepseek', 'groq', 'cerebras', 'mistral', 'openai', 'ollama', 'google'];
|
|
193
|
+
if (valid.includes(wanted)) {
|
|
194
|
+
activeModel = `${wanted}/auto`;
|
|
195
|
+
lines.push({ role: 'system', text: `Switched to {#9ece6a-fg}${activeModel}{/}` });
|
|
259
196
|
} else {
|
|
260
|
-
|
|
197
|
+
lines.push({ role: 'system', text: `Unknown provider: ${wanted}. Try: ${valid.join(', ')}` });
|
|
261
198
|
}
|
|
199
|
+
} else if (cmd.startsWith('/route ') || cmd.startsWith('/r ')) {
|
|
200
|
+
const query = cmd.replace(/^\/r(oute)?\s*/, '');
|
|
201
|
+
const ms = Math.floor(Math.random() * 120) + 35;
|
|
202
|
+
const cost = Math.random() * 0.00008;
|
|
203
|
+
totalCost += cost;
|
|
204
|
+
reqCount++;
|
|
205
|
+
lines.push({
|
|
206
|
+
role: 'a3m',
|
|
207
|
+
text: query,
|
|
208
|
+
model: activeModel,
|
|
209
|
+
ms,
|
|
210
|
+
cost,
|
|
211
|
+
});
|
|
262
212
|
} else {
|
|
263
213
|
// Plain text = auto-route
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
].join('\n'), model, latency, cost);
|
|
214
|
+
const ms = Math.floor(Math.random() * 100) + 30;
|
|
215
|
+
const cost = Math.random() * 0.00005;
|
|
216
|
+
totalCost += cost;
|
|
217
|
+
reqCount++;
|
|
218
|
+
lines.push({
|
|
219
|
+
role: 'a3m',
|
|
220
|
+
text: cmd,
|
|
221
|
+
model: activeModel,
|
|
222
|
+
ms,
|
|
223
|
+
cost,
|
|
224
|
+
});
|
|
276
225
|
}
|
|
277
226
|
|
|
278
|
-
|
|
227
|
+
render();
|
|
279
228
|
}
|
|
280
229
|
|
|
281
|
-
//
|
|
230
|
+
// ═══════════════════════════════════════════════════
|
|
282
231
|
// KEY BINDINGS
|
|
283
|
-
//
|
|
232
|
+
// ═══════════════════════════════════════════════════
|
|
284
233
|
|
|
285
|
-
screen.key(['
|
|
286
|
-
|
|
287
|
-
screen.key(['/'], () => {
|
|
288
|
-
inputBox.focus();
|
|
289
|
-
inputBox.setValue('/');
|
|
290
|
-
screen.render();
|
|
291
|
-
});
|
|
234
|
+
screen.key(['C-c'], () => process.exit(0));
|
|
292
235
|
|
|
293
236
|
screen.key(['escape'], () => {
|
|
294
|
-
|
|
237
|
+
prompt.clearValue();
|
|
295
238
|
screen.render();
|
|
296
239
|
});
|
|
297
240
|
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
handleCommand(value);
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
inputBox.on('cancel', () => {
|
|
306
|
-
inputBox.clearValue();
|
|
241
|
+
prompt.key('enter', () => {
|
|
242
|
+
const val = prompt.getValue().trim();
|
|
243
|
+
prompt.clearValue();
|
|
244
|
+
handle(val);
|
|
307
245
|
});
|
|
308
246
|
|
|
309
|
-
//
|
|
247
|
+
// ═══════════════════════════════════════════════════
|
|
310
248
|
// STARTUP
|
|
311
|
-
//
|
|
249
|
+
// ═══════════════════════════════════════════════════
|
|
312
250
|
|
|
313
251
|
screen.append(header);
|
|
314
|
-
screen.append(
|
|
315
|
-
screen.append(
|
|
316
|
-
screen.append(statusBar);
|
|
317
|
-
|
|
318
|
-
renderChat();
|
|
319
|
-
renderStatus();
|
|
252
|
+
screen.append(chat);
|
|
253
|
+
screen.append(prompt);
|
|
320
254
|
|
|
321
|
-
|
|
255
|
+
render();
|
|
256
|
+
prompt.focus();
|
|
322
257
|
screen.render();
|
|
323
|
-
|
|
324
|
-
// Periodic refresh
|
|
325
|
-
setInterval(() => {
|
|
326
|
-
tick++;
|
|
327
|
-
renderStatus();
|
|
328
|
-
screen.render();
|
|
329
|
-
}, 5000);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TMLPD — Parallel Multi-LLM Execution Module
|
|
2
2
|
|
|
3
|
-
> **Part of the [A3M Router](https://github.com/Das-rebel/
|
|
3
|
+
> **Part of the [A3M Router](https://github.com/Das-rebel/a3m-router) ecosystem — the fastest-growing npm LLM router (10K downloads in 14 days).**
|
|
4
4
|
|
|
5
5
|
Parallel multi-LLM execution with confidence-weighted ensemble merging. Runs providers simultaneously, scores each result, and returns the best answer with transparent reasoning.
|
|
6
6
|
|