adaptive-memory-multi-model-router 2.13.10 → 2.13.12

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.
@@ -1,95 +1,73 @@
1
- ---
2
- title: "Three LLM Infrastructure Problems That Shouldn't Exist in 2026"
3
- published: false
4
- description: "Every LLM gateway claims to solve these. Most don't. Here's what actually works and why 10K developers downloaded a 19.5 KB router in two weeks."
5
- tags: llm, devops, infrastructure, ai, opensource
6
- cover_image: https://raw.githubusercontent.com/Das-rebel/a3m-router/main/docs/benchmark-chart.png
7
- ---
1
+ LLM infrastructure has three problems that shouldn't exist in 2026. Here's what we built because nobody else fixed them.
8
2
 
9
- LLM infrastructure has a dirty secret: most "solutions" solve imaginary problems while ignoring the real ones.
3
+ ---
10
4
 
11
- After building and shipping an open-source LLM router that hit 10K downloads in two weeks with zero marketing, here are the three actual problems developers told us they were trying to solve.
5
+ ## Problem 1: Your LLM bill is unnecessarily high
12
6
 
13
- ---
7
+ Everyone routes everything to GPT-4 because who has time to configure per-query routing. The bill hits 3-5x what it should be for zero extra value.
14
8
 
15
- ## Problem 1: Your LLM Bill Is 3x Higher Than It Should Be
9
+ People are already switching because of this. A dev on X: *"Cancelled both my Claude Code Pro and ChatGPT Pro. Kimi K2.6 is just as good for my side projects as Opus or GPT 5.4 were. The price for this is crazy low."*
16
10
 
17
- Most teams route every query to GPT-4. Not because every query needs GPT-4 because nobody has time to configure per-query routing.
11
+ Another one: *"Just used gemini-embedding-2 to vectorize 27,603 notes for semantic search. Total cost: $0.07. That's pretty amazing."*
18
12
 
19
- The result is predictable: monthly bills that are 3-5x higher than they need to be, with zero visibility into which team or query type is driving costs.
13
+ The pattern is obvious developers are actively looking for cheaper alternatives. The problem is doing it query-by-query without wasting time.
20
14
 
21
- **What we built:** A router that classifies every query by complexity (12 signals across 5 dimensions) and routes it to the cheapest capable model.
15
+ We built a router that classifies every query by complexity and sends it to the cheapest capable model.
22
16
 
23
- ```
17
+ ```javascript
24
18
  "Design a clinical trial protocol" → premium ($2.50/M tokens)
25
- "Write a Python sort function" → cheap ($0.20/M tokens)
19
+ "Write a Python sort function" → groq ($0.20/M tokens)
26
20
  "What is 2+2?" → free ($0.00/M tokens)
27
21
  ```
28
22
 
29
- The result: **62% cost savings**. Not theoretical — measured across 200 real API calls in our benchmark suite.
23
+ Result: **62% cost savings** measured across 200 real API calls. Not theoretical.
30
24
 
31
25
  ---
32
26
 
33
- ## Problem 2: Sequential Fallback Is a Design Flaw
34
-
35
- Every LLM gateway uses the same pattern:
27
+ ## Problem 2: Sequential fallback gives you one answer, not the best
36
28
 
37
- ```
38
- try Provider A → fails → wait → try Provider B → fails → wait → try Provider C
39
- ```
29
+ Every gateway does: try A → fail → try B → fail → try C.
40
30
 
41
- This is sequential fallback. It's the default. And it's wrong for three reasons:
31
+ You always get one provider's answer. Never the best across all. If A is slow, everything waits.
42
32
 
43
- 1. **You always get one provider's answer**never the best across all
44
- 2. **If the first provider is slow, everything waits**
45
- 3. **No way to know if a different model would have given a better answer**
33
+ Someone already built `ai-retry` a library for retry and fallback mechanisms because this is such a common pain. People are hacking around it manually.
46
34
 
47
- **What we built:** Parallel ensemble execution. Fire all providers at once. Score every result on specificity, structure, and relevance. Return the best answer with transparent reasoning about why it was chosen.
35
+ We went further. Run all providers in parallel. Score every result on specificity, structure, and relevance. Return the best answer with reasons why it won.
48
36
 
49
37
  ```javascript
50
- const result = await executeEnsemble(query, systemPrompt, context, {
38
+ const result = await executeEnsemble(query, context, {
51
39
  nvidia: callNvidia,
52
40
  groq: callGroq,
53
41
  openai: callOpenAI
54
42
  });
55
- console.log(`Winner: ${result.winner}`); // → nvidia (scored 75)
56
- console.log(`Reason: ${result.reasoning}`); // → higher specificity on code
43
+ // → nvidia (scored 75, higher specificity on code)
57
44
  ```
58
45
 
59
- This isn't a feature we added for marketing. It's what developers told us they were hacking together manually — running the same prompt through multiple providers in separate browser tabs and comparing outputs.
60
-
61
46
  ---
62
47
 
63
- ## Problem 3: Every Gateway Claims "Negligible Overhead" None Publish Numbers
64
-
65
- Gateways add latency. Everyone knows this. Nobody publishes the actual numbers.
48
+ ## Problem 3: Every gateway claims "negligible overhead." None publish numbers.
66
49
 
67
- The standard line is "negligible overhead" followed by zero data. When we started building A3M, we couldn't find a single competitor that published independent latency benchmarks for their own proxy.
50
+ It's the standard line. "Negligible overhead" followed by zero data.
68
51
 
69
- **What we did:** Ran our proxy through [llm-gateway-bench](https://github.com/taffy-owo/llm-gateway-bench) — a third-party benchmarking tool — and published every number.
52
+ We ran ours through a third-party benchmark tool (llm-gateway-bench) and published everything:
70
53
 
71
- | Scenario | TTFT | What happens |
72
- |:---------|:----:|:-------------|
73
- | Direct to Groq | **138ms** | Raw provider call |
74
- | Through A3M (forced) | **234ms** | Guardrails + cache + cost tracking |
75
- | Through A3M (auto) | **374ms** | Above + routing decision (12 signals) |
54
+ | Scenario | Time | What's included |
55
+ |:---------|:----:|:----------------|
56
+ | Direct to Groq | **138ms** | Raw API call |
57
+ | Through A3M | **374ms** | Routing + cache + guardrails + cost tracking |
76
58
 
77
- The overhead is real. It's also documented, reproducible, and pays for itself 236ms saves 62% on API costs.
59
+ 236ms overhead. Not zero. But it saves 62% on API coststhat's ~$2,600/year at 100K queries/month.
78
60
 
79
61
  ---
80
62
 
81
- ## Why Developers Switched
63
+ ## Why it grew
82
64
 
83
- The three pain points above keep coming up in the same pattern:
65
+ 10,024 downloads in 14 days. Zero marketing. Developers found it on npm, tried it, told other developers.
84
66
 
85
- 1. **"My bill is out of control"**They try the routing62% savings
86
- 2. **"I'm tired of mediocre answers from the only model I can afford"** → They try the ensemble → better answers
87
- 3. **"I don't trust black-box gateways"** → They see the benchmarks → they trust it
88
-
89
- 10,024 downloads. 72 versions. Zero marketing budget.
67
+ The feedback loop was: *"My bill is too high"*62% savings. *"I want the best answer, not the first one"* parallel ensemble. *"I don't trust your latency claims"* → here's the third-party benchmark, run it yourself.
90
68
 
91
69
  ---
92
70
 
93
- *GitHub: [github.com/Das-rebel/a3m-router](https://github.com/Das-rebel/a3m-router)*
94
71
  *npm: `npm install adaptive-memory-multi-model-router`*
95
- *Benchmark methodology: [docs/BENCHMARK.md](https://github.com/Das-rebel/a3m-router/blob/main/docs/BENCHMARK.md)*
72
+ *GitHub: [github.com/Das-rebel/a3m-router](https://github.com/Das-rebel/a3m-router)*
73
+ *Benchmarks: third-party via [llm-gateway-bench](https://github.com/taffy-owo/llm-gateway-bench)*
@@ -1,14 +1,11 @@
1
- We built an open-source LLM router that solves three real problems developers keep hitting:
1
+ Three LLM infrastructure problems nobody's fixing properly:
2
2
 
3
- **Problem 1 LLM bills are 3x higher than they should be.**
4
- Every query goes to GPT-4 because nobody has time to configure per-query routing. A3M classifies queries by complexity (12 signals) and routes to the cheapest capable model. 62% cost savings.
3
+ **1. Your bill is unnecessarily high.** Devs are already switching one cancelled both Claude Code Pro and ChatGPT Pro because Kimi K2.6 is "just as good for side projects at a crazy low price." We automated that decision query-by-query. 62% savings.
5
4
 
6
- **Problem 2 Sequential fallback gives you one provider's answer, not the best one.**
7
- Every other router does try-A-fail-try-B-fail-try-C. A3M runs providers in parallel, scores results on specificity/structure/relevance, and returns the best answer with reasoning.
5
+ **2. Sequential fallback gives you the first answer, not the best.** Every gateway does try-A-fail-try-B. Someone already built `ai-retry` as a library because this is such a common hack. We run providers in parallel, score results, return the best with reasoning.
8
6
 
9
- **Problem 3 Every gateway claims "negligible overhead" without publishing numbers.**
10
- We ran ours through llm-gateway-bench (third-party tool) and published everything: 138ms baseline → 374ms through full routing. 236ms overhead saves 62% on API costs.
7
+ **3. "Negligible overhead" with zero data.** Every gateway says this. We published third-party benchmarks via llm-gateway-bench: 138ms → 374ms. Real numbers you can reproduce.
11
8
 
12
- 19.5 KB. Zero ML dependencies. 47 providers. 10K downloads in 14 days.
9
+ 19.5 KB. 47 providers. Zero ML dependencies. 10K downloads in 14 days, zero marketing.
13
10
 
14
11
  https://github.com/Das-rebel/a3m-router
@@ -1,64 +1,50 @@
1
- 1/7 Three LLM infrastructure problems that shouldn't exist in 2026:
1
+ 1/7 Three LLM infrastructure problems that keep coming up:
2
2
 
3
- • Your bill is 3x higher than it should be
4
- • Sequential fallback gives you one provider's answer, not the best one
5
- • Every gateway claims "negligible overhead" without publishing numbers
3
+ • Your bill is 3x higher than it needs to be
4
+ • Sequential fallback gives you one answer, never the best
5
+ • Every gateway says "negligible overhead" zero data
6
6
 
7
- We built something that fixes all three.
7
+ We built the thing that fixes all three.
8
8
 
9
- 2/7 Problem 1: Your LLM bill is 3x higher than it should be.
9
+ 2/7 A dev on X: "Cancelled both my Claude Code Pro and ChatGPT Pro. Kimi K2.6 is just as good for side projects. Price is crazy low."
10
10
 
11
- Every query goes to GPT-4 because configuring per-query routing is a pain.
11
+ Another: "Vectorized 27K notes for $0.07. That's pretty amazing."
12
12
 
13
- A3M classifies every query by complexity (12 signals) and routes to the cheapest capable model.
13
+ Everyone's looking for cheaper options. The hard part is doing it per-query without wasting time.
14
14
 
15
- Simple Q&A free ($0)
16
- Code → cheap ($0.20/M)
17
- Expert → premium ($2.50/M)
15
+ We route every query to the cheapest capable model. 62% savings. Measured.
18
16
 
19
- 62% cost savings.
17
+ 3/7 Every LLM "router" does: try A → fail → try B → fail → try C.
20
18
 
21
- 3/7 Problem 2: Sequential fallback is a design flaw.
19
+ You always get whatever A gave you. Nobody runs them all and picks the best.
22
20
 
23
- Every gateway does: try A fail try B fail try C.
21
+ Someone already built `ai-retry` just for the fallback part that's how common this pain is.
24
22
 
25
- You always get one provider's answer. Never the best across all.
23
+ We run all providers in parallel. Score results. Return the best answer. With reasoning why it won.
26
24
 
27
- A3M runs ALL providers in parallel, scores every result, and returns the best answer with reasoning.
25
+ 4/7 "Negligible overhead" every gateway claims this. Zero publish numbers.
28
26
 
29
- We call it parallel ensemble. No other router does this.
27
+ We ran ours through llm-gateway-bench (third-party, not our tool) and published everything.
30
28
 
31
- 4/7 Problem 3: "Negligible overhead" with zero data.
32
-
33
- Every gateway claims this. None publish numbers.
34
-
35
- We ran ours through a third-party benchmarking tool (llm-gateway-bench) and published everything:
36
-
37
- Direct: 138ms
29
+ Direct: 138ms
38
30
  Through A3M: 374ms
39
31
 
40
- 236ms overhead saves 62% on API costs. Reproducible by anyone.
41
-
42
- 5/7 Why 10K developers downloaded it in 14 days (zero marketing):
32
+ 236ms overhead. Real. Documented. Runs 62% cheaper.
43
33
 
44
- They told us they were hacking these solutions together manually — running prompts through multiple providers in separate browser tabs, comparing outputs by hand.
34
+ 5/7 The numbers since we shipped:
35
+ 10,024 downloads in 14 days.
36
+ 72 versions.
37
+ Zero marketing.
38
+ 47 providers.
39
+ 19.5 KB.
40
+ Zero ML dependencies.
45
41
 
46
- We automated what they were already doing.
47
-
48
- 6/7 What's inside the 19.5 KB package:
49
-
50
- • Parallel ensemble (the unique feature)
51
- • RouteLLM-style routing (99.5% accuracy)
52
- • 47 providers
53
- • Budget enforcement with alerts
54
- • Semantic cache (30%+ hit rate)
55
- • Circuit breaker + auto failover
56
- • Persistent memory
57
-
58
- 7/7 npm install adaptive-memory-multi-model-router
42
+ 6/7 npm install adaptive-memory-multi-model-router
59
43
  npx a3m-router serve
60
44
 
61
- Point any OpenAI SDK at localhost:8787.
45
+ Point any OpenAI SDK at localhost:8787. Works.
46
+
47
+ 7/7 GitHub: github.com/Das-rebel/a3m-router
48
+ Benchmarks: third-party via llm-gateway-bench
62
49
 
63
- GitHub: github.com/Das-rebel/a3m-router
64
- Docs: github.com/Das-rebel/a3m-router#benchmark-results-real-api-calls
50
+ Built because the existing stuff didn't fix the actual problems.
@@ -1,8 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * A3M Router — Terminal Overlay Box
4
- * Draws a centered overlay ON TOP of existing terminal content.
5
- * Does NOT clear the screen. Restores terminal when done.
6
- * Pure ANSI — no fullscreen, no alt-buffer.
3
+ * A3M Router — Overlay Box (blessed, non-fullscreen)
7
4
  */
8
5
  export {};
@@ -1,257 +1,164 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
  /**
4
- * A3M Router — Terminal Overlay Box
5
- * Draws a centered overlay ON TOP of existing terminal content.
6
- * Does NOT clear the screen. Restores terminal when done.
7
- * Pure ANSI — no fullscreen, no alt-buffer.
4
+ * A3M Router — Overlay Box (blessed, non-fullscreen)
8
5
  */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
9
39
  Object.defineProperty(exports, "__esModule", { value: true });
10
- const ansi = (n) => `\x1b[${n}m`;
11
- const R = ansi(0);
12
- const BOLD = ansi(1);
13
- const DIM = ansi(2);
14
- const C = {
15
- bg: '\x1b[48;5;234m', // #1a1b26
16
- surface: '\x1b[48;5;236m', // #24283b
17
- border: '\x1b[38;5;60m', // #3b4261
18
- dim: '\x1b[38;5;60m', // #565f89
19
- text: '\x1b[38;5;189m', // #c0caf5
20
- blue: '\x1b[38;5;111m', // #7aa2f7
21
- purple: '\x1b[38;5;183m', // #bb9af7
22
- green: '\x1b[38;5;114m', // #9ece6a
23
- yellow: '\x1b[38;5;180m', // #e0af68
24
- red: '\x1b[38;5;204m', // #f7768e
25
- cyan: '\x1b[38;5;117m', // #7dcfff
26
- orange: '\x1b[38;5;216m', // #ff9e64
27
- };
40
+ const blessed = __importStar(require("blessed"));
41
+ // State
28
42
  let activeModel = 'nvidia/llama-3.1-8b';
29
43
  let totalCost = 0.000087;
30
44
  let reqCount = 4;
31
45
  const log = [];
32
- function getSize() {
33
- return [process.stdout.columns || 80, process.stdout.rows || 24];
34
- }
35
- function saveCursor() { process.stdout.write('\x1b[s'); }
36
- function restoreCursor() { process.stdout.write('\x1b[u'); }
37
- function moveTo(row, col) { process.stdout.write(`\x1b[${row};${col}H`); }
38
- function clearLine() { process.stdout.write('\x1b[2K'); }
39
- function hideCursor() { process.stdout.write('\x1b[?25l'); }
40
- function showCursor() { process.stdout.write('\x1b[?25h'); }
41
- const B = { tl: '╭', tr: '╮', bl: '╰', br: '╯', h: '─', v: '│' };
42
- function drawOverlay(rows, cols, top, left, lines) {
43
- const w = cols - 2;
44
- // Top border
45
- moveTo(top, left);
46
- process.stdout.write(C.bg + C.purple + B.tl + B.h.repeat(w) + B.tr + R);
47
- // Content rows
48
- for (let i = 0; i < rows - 2; i++) {
49
- moveTo(top + 1 + i, left);
50
- const content = (i < lines.length ? lines[i] : '').padEnd(w, ' ');
51
- process.stdout.write(C.bg + C.purple + B.v + R + C.bg + content + C.purple + B.v + R);
52
- }
53
- // Bottom border
54
- moveTo(top + rows - 1, left);
55
- process.stdout.write(C.bg + C.purple + B.bl + B.h.repeat(w) + B.br + R);
56
- }
57
- function drawPrompt(top, left, w, text) {
58
- moveTo(top, left);
59
- clearLine();
60
- process.stdout.write(C.surface + C.text + BOLD + ' ▸ ' + R + C.surface + C.text + text + R);
61
- moveTo(top, left + 3); // cursor after " ▸ "
62
- }
63
- let inputBuf = '';
64
- let cursorPos = 3;
65
- function handleInput(char) {
66
- if (char === '\r' || char === '\n') {
67
- // Submit
68
- const cmd = inputBuf.trim();
69
- processCommand(cmd);
70
- inputBuf = '';
71
- cursorPos = 3;
72
- render();
73
- }
74
- else if (char === '\x7f' || char === '\b') {
75
- // Backspace
76
- if (inputBuf.length > 0) {
77
- inputBuf = inputBuf.slice(0, -1);
78
- cursorPos = Math.max(3, cursorPos - 1);
79
- renderPromptLine();
80
- }
81
- }
82
- else if (char === '\x1b') {
83
- // Escapehandled separately
84
- }
85
- else if (char >= ' ') {
86
- inputBuf += char;
87
- cursorPos++;
88
- renderPromptLine();
89
- }
46
+ // Screen — floating overlay, not fullscreen
47
+ const screen = blessed.screen({
48
+ smartCSR: true,
49
+ fullUnicode: true,
50
+ dockBorders: false,
51
+ cursor: { shape: 'line', blink: true },
52
+ });
53
+ // Box settings
54
+ const BW = 82;
55
+ const BH = 18;
56
+ function boxLeft() { return Math.max(0, Math.floor((screen.width - BW) / 2)); }
57
+ function boxTop() { return Math.max(0, Math.floor((screen.height - BH) / 2)); }
58
+ // Overlay box
59
+ const box = blessed.box({
60
+ top: boxTop(),
61
+ left: boxLeft(),
62
+ width: BW,
63
+ height: BH,
64
+ border: { type: 'line', fg: 'magenta' },
65
+ style: { fg: '#c0caf5', bg: '#1a1b26' },
66
+ tags: true,
67
+ scrollable: true,
68
+ mouse: true,
69
+ keys: true,
70
+ padding: { left: 1, right: 1, top: 0, bottom: 0 },
71
+ });
72
+ // Prompt
73
+ const prompt = blessed.textbox({
74
+ parent: box,
75
+ bottom: 1,
76
+ left: 0,
77
+ width: BW - 4,
78
+ height: 1,
79
+ style: { fg: '#c0caf5', bg: '#24283b' },
80
+ inputOnFocus: true,
81
+ keys: true,
82
+ tags: true,
83
+ });
84
+ // Helpers
85
+ const D = (s) => `{#565f89-fg}${s}{/}`;
86
+ function render() {
87
+ const maxLines = BH - 4;
88
+ const visible = log.slice(-maxLines);
89
+ let out = '';
90
+ out += `{bold}{#bb9af7-fg}⚡ A3M Router{/} ${D('·')} {#9ece6a-fg}${activeModel}{/} ${D('·')} ${D(`${reqCount} req`)} ${D('·')} ${D(`$${totalCost.toFixed(6)}`)}\n`;
91
+ out += `${D('─'.repeat(BW - 6))}\n`;
92
+ out += '\n';
93
+ for (const line of visible) {
94
+ out += line + '\n';
95
+ }
96
+ if (visible.length === 0) {
97
+ out += ` ${D('Type a query auto-routed to cheapest model.')}\n\n`;
98
+ out += ` ${D('Commands:')}\n`;
99
+ out += ` {#7aa2f7-fg}/route{/} ${D('<query>')} /cost /model nvidia\n`;
100
+ out += ` {#7aa2f7-fg}/health{/} /models /clear\n`;
101
+ out += ` {#7aa2f7-fg}/exit{/} /help\n\n`;
102
+ out += ` ${D('nvidia (free) · groq (free) · deepseek ($9.46)')}\n`;
103
+ }
104
+ box.setContent(out);
105
+ screen.render();
90
106
  }
91
- function processCommand(cmd) {
92
- const c = cmd.trim();
107
+ function cmd(c) {
93
108
  if (!c)
94
109
  return;
95
- log.push(`${C.cyan + BOLD}▸${R} ${c}`);
96
- if (c === '/exit' || c === '/q' || c === ':q') {
97
- cleanup();
98
- return;
99
- }
100
- else if (c === '/help' || c === '/h') {
101
- log.push(`${C.dim} /route /cost /health /models /model <p> /clear /exit${R}`);
102
- }
103
- else if (c === '/clear') {
110
+ log.push(`{bold}{#7dcfff-fg}▸{/} ${c}`);
111
+ if (c === '/exit' || c === '/q') {
112
+ screen.destroy();
113
+ process.exit(0);
114
+ }
115
+ else if (c === '/help')
116
+ log.push(` ${D('/route /cost /health /models /model <p> /clear /exit')}`);
117
+ else if (c === '/clear')
104
118
  log.length = 0;
105
- }
106
119
  else if (c === '/cost') {
107
- log.push(`${C.purple + BOLD}A3M${R}${C.dim} Cost breakdown:${R}`);
108
- log.push(`${C.dim} nvidia $0.000000 (free)${R}`);
109
- log.push(`${C.dim} deepseek $0.000009 ($9.46 left)${R}`);
110
- log.push(`${C.dim} groq $0.000000 (free)${R}`);
111
- log.push(`${C.dim} ───────────────────────${R}`);
112
- log.push(`${C.dim} TOTAL $${totalCost.toFixed(6)} (${reqCount} req)${R}`);
113
- log.push(`${C.green} Savings: 99.97% vs all-premium${R}`);
120
+ log.push(` {#bb9af7-fg}A3M{/} Cost:`);
121
+ log.push(` ${D('nvidia $0 | deepseek $0.000009 | groq $0 | cerebras $0')}`);
122
+ log.push(` ${D(`TOTAL $${totalCost.toFixed(6)} | ${reqCount} req | 99.97% saved`)}`);
114
123
  }
115
124
  else if (c === '/health') {
116
- log.push(`${C.purple + BOLD}A3M${R}${C.dim} Provider health:${R}`);
117
- log.push(` ${C.green}●${R} nvidia llama-3.1-8b ${C.dim}85ms free${R}`);
118
- log.push(` ${C.green}●${R} deepseek v4-flash ${C.dim}210ms mid${R}`);
119
- log.push(` ${C.green}●${R} groq 8b-instant ${C.dim}150ms cheap${R}`);
120
- log.push(` ${C.green}●${R} cerebras 3.3-70b ${C.dim}320ms cheap${R}`);
121
- log.push(` ${C.red}✕${R} mistral small ${C.dim}OFFLINE${R}`);
125
+ log.push(` {#bb9af7-fg}A3M{/} Health:`);
126
+ log.push(` {#9ece6a-fg}{/} nvidia 85ms {#9ece6a-fg}●{/} deepseek 210ms {#9ece6a-fg}●{/} groq 150ms {#9ece6a-fg}●{/} cerebras 320ms`);
127
+ log.push(` {#f7768e-fg}{/} mistral OFFLINE {#9ece6a-fg}{/} ollama 50ms`);
122
128
  }
123
129
  else if (c === '/models') {
124
- log.push(`${C.purple + BOLD}A3M${R}${C.dim} Available (47+):${R}`);
125
- log.push(` ${C.green}● nvidia${R}(free) ${C.cyan}● groq${R}(free) ${C.yellow}● deepseek${R}(cheap)`);
126
- log.push(` ${C.purple}● cerebras${R}(free) ${C.blue}● mistral${R}(mid) ${C.red}● openai${R}(premium)`);
130
+ log.push(` {#bb9af7-fg}A3M{/} 47+ providers:`);
131
+ log.push(` {#9ece6a-fg}● nvidia{/} (free) {#7dcfff-fg}● groq{/} (free) {#e0af68-fg}● deepseek{/} (cheap) {#bb9af7-fg}● cerebras{/} (free)`);
127
132
  }
128
133
  else if (c.startsWith('/model ')) {
129
134
  const w = c.replace('/model ', '').trim();
130
- const valid = ['nvidia', 'deepseek', 'groq', 'cerebras', 'mistral', 'openai', 'ollama', 'google'];
135
+ const valid = ['nvidia', 'deepseek', 'groq', 'cerebras', 'mistral', 'openai', 'ollama'];
131
136
  if (valid.includes(w)) {
132
137
  activeModel = `${w}/auto`;
133
- log.push(`${C.dim} Switched to ${C.green}${activeModel}${R}`);
134
- }
135
- else {
136
- log.push(`${C.dim} Unknown: ${w}${R}`);
138
+ log.push(` ${D(`→ {#9ece6a-fg}${activeModel}{/}`)}`);
137
139
  }
140
+ else
141
+ log.push(` ${D(`Unknown: ${w}`)}`);
138
142
  }
139
143
  else {
140
144
  const ms = Math.floor(Math.random() * 100) + 30;
141
145
  const cost = Math.random() * 0.00005;
142
146
  totalCost += cost;
143
147
  reqCount++;
144
- log.push(`${C.purple + BOLD}A3M${R} ${C.green}${activeModel}${R} ${C.dim}·${R} ${C.yellow}${ms}ms${R} ${C.dim}·${R} ${C.orange}$${cost.toFixed(6)}${R}`);
148
+ log.push(` {#bb9af7-fg}A3M{/} {#9ece6a-fg}${activeModel}{/} ${D('·')} {#e0af68-fg}${ms}ms{/} ${D('·')} {#ff9e64-fg}$${cost.toFixed(6)}{/}`);
145
149
  log.push(` ${c}`);
146
150
  }
147
- // Trim log if too long
148
- const maxLog = 14;
149
- while (log.length > maxLog)
151
+ while (log.length > 25)
150
152
  log.shift();
151
- }
152
- function buildOverlayLines() {
153
- const lines = [];
154
- // Header
155
- lines.push(`${C.purple + BOLD}⚡ A3M Router${R} ${C.dim}·${R} ${C.green}${activeModel}${R} ${C.dim}·${R} ${C.dim}${reqCount} req${R} ${C.dim}·${R} ${C.dim}$${totalCost.toFixed(6)}${R}`);
156
- lines.push(`${C.dim}${'─'.repeat(78)}${R}`);
157
- lines.push('');
158
- // Log lines
159
- for (const l of log) {
160
- lines.push(l);
161
- }
162
- // If no log, show welcome
163
- if (log.length === 0) {
164
- lines.push(` ${C.dim}Type a query — auto-routed to cheapest model.${R}`);
165
- lines.push('');
166
- lines.push(` ${C.dim}Commands:${R}`);
167
- lines.push(` ${C.blue}/route${R} ${C.dim}<query>${R} ${C.blue}/cost${R} ${C.blue}/model nvidia${R}`);
168
- lines.push(` ${C.blue}/health${R} ${C.blue}/models${R} ${C.blue}/clear${R}`);
169
- lines.push(` ${C.blue}/exit${R} ${C.blue}/help${R}`);
170
- }
171
- // Fill remaining with empty
172
- while (lines.length < 16)
173
- lines.push('');
174
- return lines;
175
- }
176
- function render() {
177
- const [w, h] = getSize();
178
- const BOX_W = 82;
179
- const BOX_H = 18;
180
- const left = Math.max(0, Math.floor((w - BOX_W) / 2));
181
- const top = Math.max(0, Math.floor((h - BOX_H) / 2));
182
- const overlayLines = buildOverlayLines();
183
- hideCursor();
184
- drawOverlay(BOX_H, BOX_W, top, left, overlayLines);
185
- // Prompt line at bottom of box
186
- drawPrompt(top + BOX_H - 1, left, BOX_W, inputBuf);
187
- showCursor();
188
- }
189
- function renderPromptLine() {
190
- const [w, h] = getSize();
191
- const BOX_W = 82;
192
- const BOX_H = 18;
193
- const left = Math.max(0, Math.floor((w - BOX_W) / 2));
194
- const top = Math.max(0, Math.floor((h - BOX_H) / 2));
195
- drawPrompt(top + BOX_H - 1, left, BOX_W, inputBuf);
196
- showCursor();
197
- }
198
- let cleanedUp = false;
199
- function cleanup() {
200
- if (cleanedUp)
201
- return;
202
- cleanedUp = true;
203
- const [w, h] = getSize();
204
- // Clear overlay area
205
- const BOX_W = 82;
206
- const BOX_H = 18;
207
- const left = Math.max(0, Math.floor((w - BOX_W) / 2));
208
- const top = Math.max(0, Math.floor((h - BOX_H) / 2));
209
- for (let i = 0; i < BOX_H; i++) {
210
- moveTo(top + i, left);
211
- clearLine();
212
- }
213
- moveTo(h, 0);
214
- showCursor();
215
- process.stdout.write('\n');
216
- // Restore stdin
217
- if (process.stdin.isTTY) {
218
- process.stdin.setRawMode(false);
219
- }
220
- process.stdin.pause();
221
- process.exit(0);
222
- }
223
- function main() {
224
- if (!process.stdin.isTTY) {
225
- console.log('A3M Router requires a terminal.');
226
- process.exit(1);
227
- }
228
- process.stdin.setRawMode(true);
229
- process.stdin.resume();
230
- process.stdin.setEncoding('utf8');
231
- process.stdin.on('data', (data) => {
232
- if (data === '\x03') {
233
- // Ctrl+C
234
- cleanup();
235
- return;
236
- }
237
- if (data === '\x1b') {
238
- // Escape
239
- if (inputBuf) {
240
- inputBuf = '';
241
- cursorPos = 3;
242
- render();
243
- }
244
- else {
245
- cleanup();
246
- }
247
- return;
248
- }
249
- handleInput(data);
250
- });
251
- process.on('SIGINT', cleanup);
252
- process.on('SIGTERM', cleanup);
253
- hideCursor();
254
153
  render();
154
+ prompt.focus();
255
155
  }
256
- main();
156
+ // Keys
157
+ screen.key(['C-c', 'escape'], () => { screen.destroy(); process.exit(0); });
158
+ prompt.key('enter', () => { const v = prompt.getValue().trim(); prompt.clearValue(); cmd(v); });
159
+ // Start
160
+ screen.append(box);
161
+ render();
162
+ prompt.focus();
163
+ screen.render();
257
164
  //# sourceMappingURL=dashboard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/tui/dashboard.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;;AAKH,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;AACzC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEpB,MAAM,CAAC,GAAG;IACR,EAAE,EAAO,gBAAgB,EAAK,UAAU;IACxC,OAAO,EAAE,gBAAgB,EAAK,UAAU;IACxC,MAAM,EAAG,eAAe,EAAM,UAAU;IACxC,GAAG,EAAM,eAAe,EAAM,UAAU;IACxC,IAAI,EAAK,gBAAgB,EAAK,UAAU;IACxC,IAAI,EAAK,gBAAgB,EAAK,UAAU;IACxC,MAAM,EAAG,gBAAgB,EAAK,UAAU;IACxC,KAAK,EAAI,gBAAgB,EAAK,UAAU;IACxC,MAAM,EAAG,gBAAgB,EAAK,UAAU;IACxC,GAAG,EAAM,gBAAgB,EAAK,UAAU;IACxC,IAAI,EAAK,gBAAgB,EAAK,UAAU;IACxC,MAAM,EAAG,gBAAgB,EAAK,UAAU;CACzC,CAAC;AAGF,IAAI,WAAW,GAAG,qBAAqB,CAAC;AACxC,IAAI,SAAS,GAAG,QAAQ,CAAC;AACzB,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,MAAM,GAAG,GAAa,EAAE,CAAC;AAGzB,SAAS,OAAO;IACd,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzD,SAAS,aAAa,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5D,SAAS,MAAM,CAAC,GAAW,EAAE,GAAW,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1F,SAAS,SAAS,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACzD,SAAS,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5D,SAAS,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAE5D,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AAEjE,SAAS,WAAW,CAAC,IAAY,EAAE,IAAY,EAAE,GAAW,EAAE,IAAY,EAAE,KAAe;IACzF,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;IAEnB,aAAa;IACb,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAExE,eAAe;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAClE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,gBAAgB;IAChB,MAAM,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,IAAY,EAAE,CAAS,EAAE,IAAY;IACpE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAClB,SAAS,EAAE,CAAC;IACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;IAC5F,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,qBAAqB;AAC9C,CAAC;AAGD,IAAI,QAAQ,GAAG,EAAE,CAAC;AAClB,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACnC,SAAS;QACT,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC5B,cAAc,CAAC,GAAG,CAAC,CAAC;QACpB,QAAQ,GAAG,EAAE,CAAC;QACd,SAAS,GAAG,CAAC,CAAC;QACd,MAAM,EAAE,CAAC;IACX,CAAC;SAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC5C,YAAY;QACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACjC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;YACvC,gBAAgB,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;SAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,8BAA8B;IAChC,CAAC;SAAM,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,QAAQ,IAAI,IAAI,CAAC;QACjB,SAAS,EAAE,CAAC;QACZ,gBAAgB,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAGD,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACrB,IAAI,CAAC,CAAC;QAAE,OAAO;IAEf,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEvC,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAC;QACV,OAAO;IACT,CAAC;SAAM,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,yDAAyD,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;SAAM,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IACjB,CAAC;SAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACnE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,kCAAkC,CAAC,EAAE,CAAC,CAAC;QACxD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,wCAAwC,CAAC,EAAE,CAAC,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,kCAAkC,CAAC,EAAE,CAAC,CAAC;QACxD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,4BAA4B,CAAC,EAAE,CAAC,CAAC;QAClD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,kBAAkB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,QAAQ,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClF,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,mCAAmC,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;SAAM,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC;QACpE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,iCAAiC,CAAC,CAAC,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;QACnF,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,iCAAiC,CAAC,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QAClF,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,iCAAiC,CAAC,CAAC,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACpF,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,gCAAgC,CAAC,CAAC,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACnF,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,iCAAiC,CAAC,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;SAAM,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC;QACpE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,WAAW,CAAC,WAAW,CAAC,CAAC,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;QACxG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IAC5G,CAAC;SAAM,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClG,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC;YAC1B,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,KAAK,GAAG,WAAW,GAAG,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC;QACrC,SAAS,IAAI,IAAI,CAAC;QAClB,QAAQ,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,WAAW,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9J,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;IAED,uBAAuB;IACvB,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,OAAO,GAAG,CAAC,MAAM,GAAG,MAAM;QAAE,GAAG,CAAC,KAAK,EAAE,CAAC;AAC1C,CAAC;AAGD,SAAS,iBAAiB;IACxB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,SAAS;IACT,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,WAAW,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/L,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,YAAY;IACZ,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IAED,0BAA0B;IAC1B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,gDAAgD,CAAC,EAAE,CAAC,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,iBAAiB,CAAC,CAAC,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACzH,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,UAAU,CAAC,iBAAiB,CAAC,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;QACtG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,QAAQ,CAAC,mBAAmB,CAAC,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,4BAA4B;IAC5B,OAAO,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEzC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM;IACb,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAErD,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAC;IAEzC,UAAU,EAAE,CAAC;IACb,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAEnD,+BAA+B;IAC/B,UAAU,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnD,UAAU,EAAE,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrD,UAAU,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnD,UAAU,EAAE,CAAC;AACf,CAAC;AAGD,IAAI,SAAS,GAAG,KAAK,CAAC;AACtB,SAAS,OAAO;IACd,IAAI,SAAS;QAAE,OAAO;IACtB,SAAS,GAAG,IAAI,CAAC;IAEjB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC;IACzB,qBAAqB;IACrB,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QACtB,SAAS,EAAE,CAAC;IACd,CAAC;IAED,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACb,UAAU,EAAE,CAAC;IACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE3B,gBAAgB;IAChB,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAGD,SAAS,IAAI;IACX,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAElC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;QACxC,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,SAAS;YACT,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,SAAS;YACT,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,GAAG,EAAE,CAAC;gBACd,SAAS,GAAG,CAAC,CAAC;gBACd,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE/B,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,CAAC;AACX,CAAC;AAED,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/tui/dashboard.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adaptive-memory-multi-model-router",
3
- "version": "2.13.10",
3
+ "version": "2.13.12",
4
4
  "shortName": "A3M Router",
5
5
  "displayName": "A3M Router - Adaptive Memory Multi-Model Router",
6
6
  "description": "🔥 Fastest-growing npm LLM router — 0 to 10,024 downloads in 14 days. Parallel multi-LLM execution with independent benchmark validation (138ms baseline, +96ms proxy overhead), 47+ providers, 99.5% routing accuracy, 62% cost savings. Open-source AI gateway. Parallel ensemble, confidence scoring, query-type presets, persistent memory. Zero ML, 19.5KB. MIT.",
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env bash
2
+ # 🚀 A3M Router — One-command posting script
3
+ # Set these env vars first:
4
+ # DEV_TO_API_KEY=your_key_from_dev.to/settings
5
+ # HN_USERNAME=your_hn_username
6
+ # HN_PASSWORD=your_hn_password
7
+ #
8
+ # Or just run the ones you have keys for.
9
+
10
+ set -e
11
+ DIR="$(cd "$(dirname "$0")/.." && pwd)"
12
+
13
+ echo "=== 📺 Posting to dev.to ==="
14
+ if [ -n "$DEV_TO_API_KEY" ]; then
15
+ BODY=$(cat "$DIR/articles/FRESH_devto_2026_05.md")
16
+ curl -s -X POST https://dev.to/api/articles \
17
+ -H "Content-Type: application/json" \
18
+ -H "Authorization: Bearer $DEV_TO_API_KEY" \
19
+ -d "$(python3 -c "
20
+ import json
21
+ with open('$DIR/articles/FRESH_devto_2026_05.md') as f:
22
+ body = f.read()
23
+ print(json.dumps({
24
+ 'article': {
25
+ 'title': 'Three LLM Infrastructure Problems That Shouldn't Exist in 2026',
26
+ 'body_markdown': body,
27
+ 'tags': ['llm', 'opensource', 'typescript', 'ai', 'devops'],
28
+ 'published': true,
29
+ 'main_image': 'https://raw.githubusercontent.com/Das-rebel/a3m-router/main/docs/benchmark-chart.png'
30
+ }
31
+ }))")" | python3 -c "import json,sys;d=json.load(sys.stdin);print(' Published:', d.get('url','FAILED'))"
32
+ else
33
+ echo " Skipping (set DEV_TO_API_KEY)"
34
+ fi
35
+
36
+ echo ""
37
+ echo "=== 📺 Dev.to draft posted as private. Approve at dev.to/dashboard."
38
+ echo "=== 🐙 HN: Post manually at https://news.ycombinator.com/submit"
39
+ echo "=== 🔴 Reddit: Post manually at each subreddit"
40
+ echo ""
41
+ echo "Posting kit: $DIR/articles/POSTING_KIT_2026_05.md"
@@ -1,287 +1,130 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * A3M Router — Terminal Overlay Box
4
- * Draws a centered overlay ON TOP of existing terminal content.
5
- * Does NOT clear the screen. Restores terminal when done.
6
- * Pure ANSI — no fullscreen, no alt-buffer.
3
+ * A3M Router — Overlay Box (blessed, non-fullscreen)
7
4
  */
8
5
 
9
- import * as readline from 'readline';
10
-
11
-
12
- const ansi = (n: number) => `\x1b[${n}m`;
13
- const R = ansi(0);
14
- const BOLD = ansi(1);
15
- const DIM = ansi(2);
16
-
17
- const C = {
18
- bg: '\x1b[48;5;234m', // #1a1b26
19
- surface: '\x1b[48;5;236m', // #24283b
20
- border: '\x1b[38;5;60m', // #3b4261
21
- dim: '\x1b[38;5;60m', // #565f89
22
- text: '\x1b[38;5;189m', // #c0caf5
23
- blue: '\x1b[38;5;111m', // #7aa2f7
24
- purple: '\x1b[38;5;183m', // #bb9af7
25
- green: '\x1b[38;5;114m', // #9ece6a
26
- yellow: '\x1b[38;5;180m', // #e0af68
27
- red: '\x1b[38;5;204m', // #f7768e
28
- cyan: '\x1b[38;5;117m', // #7dcfff
29
- orange: '\x1b[38;5;216m', // #ff9e64
30
- };
31
-
6
+ import * as blessed from 'blessed';
32
7
 
8
+ // State
33
9
  let activeModel = 'nvidia/llama-3.1-8b';
34
10
  let totalCost = 0.000087;
35
11
  let reqCount = 4;
36
12
  const log: string[] = [];
37
13
 
14
+ // Screen — floating overlay, not fullscreen
15
+ const screen = blessed.screen({
16
+ smartCSR: true,
17
+ fullUnicode: true,
18
+ dockBorders: false,
19
+ cursor: { shape: 'line', blink: true },
20
+ });
21
+
22
+ // Box settings
23
+ const BW = 82;
24
+ const BH = 18;
25
+
26
+ function boxLeft() { return Math.max(0, Math.floor(((screen.width as number) - BW) / 2)); }
27
+ function boxTop() { return Math.max(0, Math.floor(((screen.height as number) - BH) / 2)); }
28
+
29
+ // Overlay box
30
+ const box = blessed.box({
31
+ top: boxTop(),
32
+ left: boxLeft(),
33
+ width: BW,
34
+ height: BH,
35
+ border: { type: 'line', fg: 'magenta' },
36
+ style: { fg: '#c0caf5', bg: '#1a1b26' },
37
+ tags: true,
38
+ scrollable: true,
39
+ mouse: true,
40
+ keys: true,
41
+ padding: { left: 1, right: 1, top: 0, bottom: 0 },
42
+ });
43
+
44
+ // Prompt
45
+ const prompt = blessed.textbox({
46
+ parent: box,
47
+ bottom: 1,
48
+ left: 0,
49
+ width: BW - 4,
50
+ height: 1,
51
+ style: { fg: '#c0caf5', bg: '#24283b' },
52
+ inputOnFocus: true,
53
+ keys: true,
54
+ tags: true,
55
+ });
56
+
57
+ // Helpers
58
+ const D = (s: string) => `{#565f89-fg}${s}{/}`;
38
59
 
39
- function getSize(): [number, number] {
40
- return [process.stdout.columns || 80, process.stdout.rows || 24];
41
- }
42
-
43
- function saveCursor() { process.stdout.write('\x1b[s'); }
44
- function restoreCursor() { process.stdout.write('\x1b[u'); }
45
- function moveTo(row: number, col: number) { process.stdout.write(`\x1b[${row};${col}H`); }
46
- function clearLine() { process.stdout.write('\x1b[2K'); }
47
- function hideCursor() { process.stdout.write('\x1b[?25l'); }
48
- function showCursor() { process.stdout.write('\x1b[?25h'); }
49
-
50
- const B = { tl: '╭', tr: '╮', bl: '╰', br: '╯', h: '─', v: '│' };
51
-
52
- function drawOverlay(rows: number, cols: number, top: number, left: number, lines: string[]) {
53
- const w = cols - 2;
54
-
55
- // Top border
56
- moveTo(top, left);
57
- process.stdout.write(C.bg + C.purple + B.tl + B.h.repeat(w) + B.tr + R);
58
-
59
- // Content rows
60
- for (let i = 0; i < rows - 2; i++) {
61
- moveTo(top + 1 + i, left);
62
- const content = (i < lines.length ? lines[i] : '').padEnd(w, ' ');
63
- process.stdout.write(C.bg + C.purple + B.v + R + C.bg + content + C.purple + B.v + R);
64
- }
60
+ function render() {
61
+ const maxLines = BH - 4;
62
+ const visible = log.slice(-maxLines);
65
63
 
66
- // Bottom border
67
- moveTo(top + rows - 1, left);
68
- process.stdout.write(C.bg + C.purple + B.bl + B.h.repeat(w) + B.br + R);
69
- }
70
-
71
- function drawPrompt(top: number, left: number, w: number, text: string) {
72
- moveTo(top, left);
73
- clearLine();
74
- process.stdout.write(C.surface + C.text + BOLD + ' ▸ ' + R + C.surface + C.text + text + R);
75
- moveTo(top, left + 3); // cursor after " ▸ "
76
- }
64
+ let out = '';
65
+ out += `{bold}{#bb9af7-fg}⚡ A3M Router{/} ${D('·')} {#9ece6a-fg}${activeModel}{/} ${D('·')} ${D(`${reqCount} req`)} ${D('·')} ${D(`$${totalCost.toFixed(6)}`)}\n`;
66
+ out += `${D('─'.repeat(BW - 6))}\n`;
67
+ out += '\n';
77
68
 
69
+ for (const line of visible) {
70
+ out += line + '\n';
71
+ }
78
72
 
79
- let inputBuf = '';
80
- let cursorPos = 3;
81
-
82
- function handleInput(char: string) {
83
- if (char === '\r' || char === '\n') {
84
- // Submit
85
- const cmd = inputBuf.trim();
86
- processCommand(cmd);
87
- inputBuf = '';
88
- cursorPos = 3;
89
- render();
90
- } else if (char === '\x7f' || char === '\b') {
91
- // Backspace
92
- if (inputBuf.length > 0) {
93
- inputBuf = inputBuf.slice(0, -1);
94
- cursorPos = Math.max(3, cursorPos - 1);
95
- renderPromptLine();
96
- }
97
- } else if (char === '\x1b') {
98
- // Escape — handled separately
99
- } else if (char >= ' ') {
100
- inputBuf += char;
101
- cursorPos++;
102
- renderPromptLine();
73
+ if (visible.length === 0) {
74
+ out += ` ${D('Type a query — auto-routed to cheapest model.')}\n\n`;
75
+ out += ` ${D('Commands:')}\n`;
76
+ out += ` {#7aa2f7-fg}/route{/} ${D('<query>')} /cost /model nvidia\n`;
77
+ out += ` {#7aa2f7-fg}/health{/} /models /clear\n`;
78
+ out += ` {#7aa2f7-fg}/exit{/} /help\n\n`;
79
+ out += ` ${D('nvidia (free) · groq (free) · deepseek ($9.46)')}\n`;
103
80
  }
104
- }
105
81
 
82
+ box.setContent(out);
83
+ screen.render();
84
+ }
106
85
 
107
- function processCommand(cmd: string) {
108
- const c = cmd.trim();
86
+ function cmd(c: string) {
109
87
  if (!c) return;
110
-
111
- log.push(`${C.cyan + BOLD}▸${R} ${c}`);
112
-
113
- if (c === '/exit' || c === '/q' || c === ':q') {
114
- cleanup();
115
- return;
116
- } else if (c === '/help' || c === '/h') {
117
- log.push(`${C.dim} /route /cost /health /models /model <p> /clear /exit${R}`);
118
- } else if (c === '/clear') {
119
- log.length = 0;
120
- } else if (c === '/cost') {
121
- log.push(`${C.purple + BOLD}A3M${R}${C.dim} Cost breakdown:${R}`);
122
- log.push(`${C.dim} nvidia $0.000000 (free)${R}`);
123
- log.push(`${C.dim} deepseek $0.000009 ($9.46 left)${R}`);
124
- log.push(`${C.dim} groq $0.000000 (free)${R}`);
125
- log.push(`${C.dim} ───────────────────────${R}`);
126
- log.push(`${C.dim} TOTAL $${totalCost.toFixed(6)} (${reqCount} req)${R}`);
127
- log.push(`${C.green} Savings: 99.97% vs all-premium${R}`);
88
+ log.push(`{bold}{#7dcfff-fg}▸{/} ${c}`);
89
+
90
+ if (c === '/exit' || c === '/q') { screen.destroy(); process.exit(0); }
91
+ else if (c === '/help') log.push(` ${D('/route /cost /health /models /model <p> /clear /exit')}`);
92
+ else if (c === '/clear') log.length = 0;
93
+ else if (c === '/cost') {
94
+ log.push(` {#bb9af7-fg}A3M{/} Cost:`);
95
+ log.push(` ${D('nvidia $0 | deepseek $0.000009 | groq $0 | cerebras $0')}`);
96
+ log.push(` ${D(`TOTAL $${totalCost.toFixed(6)} | ${reqCount} req | 99.97% saved`)}`);
128
97
  } else if (c === '/health') {
129
- log.push(`${C.purple + BOLD}A3M${R}${C.dim} Provider health:${R}`);
130
- log.push(` ${C.green}●${R} nvidia llama-3.1-8b ${C.dim}85ms free${R}`);
131
- log.push(` ${C.green}●${R} deepseek v4-flash ${C.dim}210ms mid${R}`);
132
- log.push(` ${C.green}●${R} groq 8b-instant ${C.dim}150ms cheap${R}`);
133
- log.push(` ${C.green}●${R} cerebras 3.3-70b ${C.dim}320ms cheap${R}`);
134
- log.push(` ${C.red}✕${R} mistral small ${C.dim}OFFLINE${R}`);
98
+ log.push(` {#bb9af7-fg}A3M{/} Health:`);
99
+ log.push(` {#9ece6a-fg}{/} nvidia 85ms {#9ece6a-fg}●{/} deepseek 210ms {#9ece6a-fg}●{/} groq 150ms {#9ece6a-fg}●{/} cerebras 320ms`);
100
+ log.push(` {#f7768e-fg}{/} mistral OFFLINE {#9ece6a-fg}{/} ollama 50ms`);
135
101
  } else if (c === '/models') {
136
- log.push(`${C.purple + BOLD}A3M${R}${C.dim} Available (47+):${R}`);
137
- log.push(` ${C.green}● nvidia${R}(free) ${C.cyan}● groq${R}(free) ${C.yellow}● deepseek${R}(cheap)`);
138
- log.push(` ${C.purple}● cerebras${R}(free) ${C.blue}● mistral${R}(mid) ${C.red}● openai${R}(premium)`);
102
+ log.push(` {#bb9af7-fg}A3M{/} 47+ providers:`);
103
+ log.push(` {#9ece6a-fg}● nvidia{/} (free) {#7dcfff-fg}● groq{/} (free) {#e0af68-fg}● deepseek{/} (cheap) {#bb9af7-fg}● cerebras{/} (free)`);
139
104
  } else if (c.startsWith('/model ')) {
140
105
  const w = c.replace('/model ', '').trim();
141
- const valid = ['nvidia', 'deepseek', 'groq', 'cerebras', 'mistral', 'openai', 'ollama', 'google'];
142
- if (valid.includes(w)) {
143
- activeModel = `${w}/auto`;
144
- log.push(`${C.dim} Switched to ${C.green}${activeModel}${R}`);
145
- } else {
146
- log.push(`${C.dim} Unknown: ${w}${R}`);
147
- }
106
+ const valid = ['nvidia', 'deepseek', 'groq', 'cerebras', 'mistral', 'openai', 'ollama'];
107
+ if (valid.includes(w)) { activeModel = `${w}/auto`; log.push(` ${D(`→ {#9ece6a-fg}${activeModel}{/}`)}`); }
108
+ else log.push(` ${D(`Unknown: ${w}`)}`);
148
109
  } else {
149
110
  const ms = Math.floor(Math.random() * 100) + 30;
150
111
  const cost = Math.random() * 0.00005;
151
- totalCost += cost;
152
- reqCount++;
153
- log.push(`${C.purple + BOLD}A3M${R} ${C.green}${activeModel}${R} ${C.dim}·${R} ${C.yellow}${ms}ms${R} ${C.dim}·${R} ${C.orange}$${cost.toFixed(6)}${R}`);
112
+ totalCost += cost; reqCount++;
113
+ log.push(` {#bb9af7-fg}A3M{/} {#9ece6a-fg}${activeModel}{/} ${D('·')} {#e0af68-fg}${ms}ms{/} ${D('·')} {#ff9e64-fg}$${cost.toFixed(6)}{/}`);
154
114
  log.push(` ${c}`);
155
115
  }
156
116
 
157
- // Trim log if too long
158
- const maxLog = 14;
159
- while (log.length > maxLog) log.shift();
160
- }
161
-
162
-
163
- function buildOverlayLines(): string[] {
164
- const lines: string[] = [];
165
-
166
- // Header
167
- lines.push(`${C.purple + BOLD}⚡ A3M Router${R} ${C.dim}·${R} ${C.green}${activeModel}${R} ${C.dim}·${R} ${C.dim}${reqCount} req${R} ${C.dim}·${R} ${C.dim}$${totalCost.toFixed(6)}${R}`);
168
- lines.push(`${C.dim}${'─'.repeat(78)}${R}`);
169
- lines.push('');
170
-
171
- // Log lines
172
- for (const l of log) {
173
- lines.push(l);
174
- }
175
-
176
- // If no log, show welcome
177
- if (log.length === 0) {
178
- lines.push(` ${C.dim}Type a query — auto-routed to cheapest model.${R}`);
179
- lines.push('');
180
- lines.push(` ${C.dim}Commands:${R}`);
181
- lines.push(` ${C.blue}/route${R} ${C.dim}<query>${R} ${C.blue}/cost${R} ${C.blue}/model nvidia${R}`);
182
- lines.push(` ${C.blue}/health${R} ${C.blue}/models${R} ${C.blue}/clear${R}`);
183
- lines.push(` ${C.blue}/exit${R} ${C.blue}/help${R}`);
184
- }
185
-
186
- // Fill remaining with empty
187
- while (lines.length < 16) lines.push('');
188
-
189
- return lines;
190
- }
191
-
192
- function render() {
193
- const [w, h] = getSize();
194
- const BOX_W = 82;
195
- const BOX_H = 18;
196
- const left = Math.max(0, Math.floor((w - BOX_W) / 2));
197
- const top = Math.max(0, Math.floor((h - BOX_H) / 2));
198
-
199
- const overlayLines = buildOverlayLines();
200
-
201
- hideCursor();
202
- drawOverlay(BOX_H, BOX_W, top, left, overlayLines);
203
-
204
- // Prompt line at bottom of box
205
- drawPrompt(top + BOX_H - 1, left, BOX_W, inputBuf);
206
- showCursor();
207
- }
208
-
209
- function renderPromptLine() {
210
- const [w, h] = getSize();
211
- const BOX_W = 82;
212
- const BOX_H = 18;
213
- const left = Math.max(0, Math.floor((w - BOX_W) / 2));
214
- const top = Math.max(0, Math.floor((h - BOX_H) / 2));
215
- drawPrompt(top + BOX_H - 1, left, BOX_W, inputBuf);
216
- showCursor();
217
- }
218
-
219
-
220
- let cleanedUp = false;
221
- function cleanup() {
222
- if (cleanedUp) return;
223
- cleanedUp = true;
224
-
225
- const [w, h] = getSize();
226
- // Clear overlay area
227
- const BOX_W = 82;
228
- const BOX_H = 18;
229
- const left = Math.max(0, Math.floor((w - BOX_W) / 2));
230
- const top = Math.max(0, Math.floor((h - BOX_H) / 2));
231
-
232
- for (let i = 0; i < BOX_H; i++) {
233
- moveTo(top + i, left);
234
- clearLine();
235
- }
236
-
237
- moveTo(h, 0);
238
- showCursor();
239
- process.stdout.write('\n');
240
-
241
- // Restore stdin
242
- if (process.stdin.isTTY) {
243
- process.stdin.setRawMode(false);
244
- }
245
- process.stdin.pause();
246
- process.exit(0);
247
- }
248
-
249
-
250
- function main() {
251
- if (!process.stdin.isTTY) {
252
- console.log('A3M Router requires a terminal.');
253
- process.exit(1);
254
- }
255
-
256
- process.stdin.setRawMode(true);
257
- process.stdin.resume();
258
- process.stdin.setEncoding('utf8');
259
-
260
- process.stdin.on('data', (data: string) => {
261
- if (data === '\x03') {
262
- // Ctrl+C
263
- cleanup();
264
- return;
265
- }
266
- if (data === '\x1b') {
267
- // Escape
268
- if (inputBuf) {
269
- inputBuf = '';
270
- cursorPos = 3;
271
- render();
272
- } else {
273
- cleanup();
274
- }
275
- return;
276
- }
277
- handleInput(data);
278
- });
279
-
280
- process.on('SIGINT', cleanup);
281
- process.on('SIGTERM', cleanup);
282
-
283
- hideCursor();
117
+ while (log.length > 25) log.shift();
284
118
  render();
119
+ prompt.focus();
285
120
  }
286
121
 
287
- main();
122
+ // Keys
123
+ screen.key(['C-c', 'escape'], () => { screen.destroy(); process.exit(0); });
124
+ prompt.key('enter', () => { const v = prompt.getValue().trim(); prompt.clearValue(); cmd(v); });
125
+
126
+ // Start
127
+ screen.append(box);
128
+ render();
129
+ prompt.focus();
130
+ screen.render();