krusch-cascade-router 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,156 +3,523 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- <strong>Latency-aware LLM router that dynamically cascades between edge and cloud models via logprob inspection.</strong>
6
+ <strong>Dual-Stage (L1 Heuristic Fast-Path + L2 Neural Semantic Escalation) Cascade Router for LLM Swarms.</strong><br>
7
+ <span>Intercepts structured code, SQL, math, and closed-world tasks in CPU microseconds (&lt;15µs) for $0.00, with integrated Level 2 (L2) neural centroid classification for unstructured chat and speculative multi-model cascades.</span>
7
8
  </p>
8
9
 
9
10
  <p align="center">
10
11
  <a href="https://www.npmjs.com/package/krusch-cascade-router"><img src="https://img.shields.io/github/package-json/v/kruschdev/krusch-cascade-router.svg?style=flat-square" alt="NPM Version"></a>
12
+ <a href="https://github.com/kruschdev/krusch-pre-router"><img src="https://img.shields.io/badge/Powered%20By-krusch--pre--router-green.svg?style=flat-square" alt="Powered By krusch-pre-router"></a>
13
+ <a href="https://github.com/kruschdev/krusch-context-mcp"><img src="https://img.shields.io/badge/L2%20Neural-krusch--context--mcp-purple.svg?style=flat-square" alt="L2 Neural krusch-context-mcp"></a>
11
14
  <a href="https://github.com/kruschdev/krusch-cascade-router/blob/main/LICENSE"><img src="https://img.shields.io/github/license/kruschdev/krusch-cascade-router.svg?style=flat-square" alt="License"></a>
12
15
  <img src="https://img.shields.io/badge/node-%3E%3D18-blue.svg?style=flat-square" alt="Node Version">
16
+ <img src="https://img.shields.io/badge/OpenRouter-5--Model%20Specialists-purple.svg?style=flat-square" alt="OpenRouter Specialists">
17
+ <a href="https://github.com/RouteWorks/RouterArena/pull/169"><img src="https://img.shields.io/badge/RouterArena-PR%20%23169%20Candidate%20(Pending%20Review)-orange.svg?style=flat-square" alt="RouterArena PR #169"></a>
18
+ <img src="https://img.shields.io/badge/tests-51%20passed-brightgreen.svg?style=flat-square" alt="Tests Passed">
13
19
  </p>
14
20
 
15
21
  ---
16
22
 
17
- ## ⚡ Why Krusch Cascade Router?
23
+ ## ⚡ The Dual-Stage Routing Pattern: "Don't spend a model call just to pick a model."
18
24
 
19
- **"LLM routing an LLM is a trap."**
25
+ > 💡 **Looking for just the zero-dependency L1 pre-filter?** If you already have an LLM client or neural router and only need the fast microsecond gate function, install [`krusch-pre-router`](https://github.com/kruschdev/krusch-pre-router) (`npm install krusch-pre-router`, 0 dependencies, <10KB gzipped).
20
26
 
21
- Using a massive third LLM to decide which LLM to route a query to adds severe TTFT (Time To First Token) latency and API costs. `krusch-cascade-router` solves this by combining a fast predictive heuristic classifier (<50ms latency) with a reactive logprob-based speculative cascade. Designed specifically for agentic developers building with local AI, it allows you to optimize for cost, performance, and reliability without sacrificing capability.
27
+ In CPU architecture, the processor does not query main RAM or NVMe storage for every instruction—it checks the **L1 cache** in 1 clock cycle. If there is an L1 hit, execution proceeds instantly with zero memory bus overhead.
28
+
29
+ In multi-model agent systems, using an LLM or neural embedding model to decide where to route an obvious Python script, SQL query, LaTeX proof, or JSON transform is an expensive anti-pattern:
30
+ * **The Routing Tax**: Adds **300ms–800ms of Time-To-First-Token (TTFT)** and auxiliary prompt token charges to every single step in an agentic loop.
31
+ * **The Dual-Stage Solution**: `krusch-cascade-router` unifies **Stage 1 (L1) Pre-Router Gating** (powered by [`krusch-pre-router`](https://github.com/kruschdev/krusch-pre-router)) with **Stage 2 (L2) Neural Semantic Escalation** (powered by [`krusch-context-mcp`](https://github.com/kruschdev/krusch-context-mcp) or in-process centroid embeddings). It executes high-confidence structured traffic in < 15 microseconds on CPU for **$0.00**, while seamlessly escalating ambiguous, conversational chat to an **L2 Neural Centroid Classifier** before dispatching across the 5-model specialist pool or frontier models.
32
+
33
+ 1. **⚡ Sub-Millisecond L1 Pre-Filter**: Evaluates syntax, query length, structure, and domain keywords in microseconds on CPU without making pre-flight routing calls (powered by `krusch-pre-router`).
34
+ 2. **🧠 Level 2 (L2) Neural Semantic Escalation**: Classifies unstructured or ambiguous prompts via vector centroid cosine distance (`createCentroidSemanticRouter` or `createContextMcpRouter`), eliminating blind defaults.
35
+ 3. **🎯 5-Model Specialist Routing via OpenRouter**: Out-of-the-box factory preset orchestrating 5 specialized domain models (`gemini-3.1-flash-lite`, `deepseek-v4-flash`, `Qwen3-Coder-Next`, `deepseek-v4-pro`, and `qwen3-235b-a22b-2507`) unified through OpenRouter. Fully swappable via `customModels`.
36
+ 4. **🧠 Knowledge Boundary Routing**: Detects closed-world self-contained tasks (syntax, math, regex, formatting, translation) to keep them on fast edge models.
37
+ 5. **⚡ Speculative Parallel Hedging**: Pre-warms heavy models in parallel on borderline confidence queries (`[0.25, 0.70]`) to mask sequential cascade latency.
38
+ 6. **🛡️ Logprob & Silent Failure Gating**: Inspects initial token logprob confidence and monitors sliding-window repetition / $n$-gram loops to abort unhelpful outputs early.
39
+
40
+ ---
41
+
42
+ ### 🎯 When to Use vs. When NOT to Use
43
+
44
+ | Best Used For ✅ | Poor Fit / Not Recommended ❌ |
45
+ |:---|:---|
46
+ | **Agentic Loops & Microservices**: Multi-step workflows where saving 300–800ms TTFT routing overhead per tool call compounds significantly. | **Open-Ended Conversational Chat**: Ambiguous, chatty, or emotional dialogue where prompt intent lacks lexical or structural domain clues. |
47
+ | **Code, STEM, Math, SQL, Formatting**: Tasks with distinct syntactic, mathematical, or structural footprints. | **Subtle Semantic Nuance**: Prompts requiring complex affective or social reasoning without explicit domain vocabulary. |
48
+ | **Closed-World Transformations**: Unit conversions, regex generation, JSON parsing, language translation. | **Latency-Insensitive Frontier Batch Jobs**: Offline tasks where maximum reasoning depth is required on 100% of inputs regardless of cost. |
49
+ | **Runaway Loop & Degeneration Guard**: Halting repetitive cyclical outputs mid-stream before blowing token limits. | **Single-Provider Monoliths**: Workloads already locked into a single proprietary model endpoint with fixed enterprise pricing. |
50
+ | **Cost-Sensitive OpenRouter Workflows**: Dispatches to cheap specialized models first with automatic fallback to frontier models. | **When You Need Learned Embeddings**: If queries are noisy, unstructured natural language, a neural router (e.g. RouteLLM, NotDiamond) will outperform regex heuristics. |
51
+
52
+ ---
53
+
54
+ ### ⚖️ Engineering Snapshot & Design Trade-offs
55
+
56
+ | Dimension | Krusch Cascade Router (Dual-Stage L1/L2) | Embedding / Neural Routers (e.g. RouteLLM) | LLM-as-a-Router (e.g. Orca) |
57
+ |---|---|---|---|
58
+ | **Dispatch Latency** | **< 15 µs (L1 Fast-Path) / ~20ms (L2 Neural)** | 15 – 50 ms (Vectorization + MLP) | 400 – 1,200 ms (LLM pre-flight) |
59
+ | **Routing Cost** | **$0.00 (L1 Fast-Path) / $0.00 local (L2)** | ~$0.0001 (Embedding tokens) | ~$0.002 (Prompt tokens) |
60
+ | **Structured Prompts (Code, Math, Syntax)** | **High Precision (>95%)** | High (>90%) | High (>95%) |
61
+ | **Messy / Ambiguous Chat** | **Robust (>92% via L2 Centroid Escalation)** | **Robust (Learns semantic nuances)** | **Very Robust** |
62
+ | **Mid-Stream Loop Guard** | **Yes (sliding n-gram abort)** | No (Routing only) | No (Routing only) |
63
+ | **Model Catalog Dependency** | **Fully decoupled (via customModels)** | Requires retrained classifier | Prompt updates |
64
+ | **Network Failure Cascade** | **Yes (Speculative dual-call & fallback)** | No | No |
65
+
66
+ ---
22
67
 
23
68
  ### Key Features
24
- - **🚀 Sub-50ms Heuristic Classifier:** Evaluates prompt complexity instantly.
25
- - **🧠 Logprob Speculative Execution:** Reactively cascades to heavy cloud models if the edge model's confidence drops.
26
- - **🔌 Framework Agnostic:** Can be plugged into any Node.js AI architecture.
27
- - **🛡️ Custom Heuristics:** Support for `customRules` to inject your own prompt complexity detection logic.
28
- - **🛑 Native AbortSignal Support:** Manage request timeouts natively via `ChatOptions`.
29
- - **📦 Dual CJS/ESM Support:** Works in modern ECMAScript and legacy environments.
69
+
70
+ * **🚀 Sub-Millisecond Routing Overhead**: Heuristic CPU classifier runs in microseconds without pre-flight network round-trips.
71
+ * **🌐 OpenRouter Provider Integration**: Built-in support for OpenRouter's unified endpoint with standard attribution headers.
72
+ * **🎯 5-Model Specialist Architecture**: Factory configuring models across code, factual STEM, deep reasoning, games, and comprehension.
73
+ * **🧠 Knowledge Boundary Router**: Classifies closed-world vs. open-world self-containment.
74
+ * **⚡ Speculative Parallel Hedging**: Hedged parallel execution for borderline prompts to mask cascade latency.
75
+ * **🛡️ Mid-Stream Loop Guard**: Catches degenerate repetition loops and token stagnation.
76
+ * **🧪 Developer Integration Test Suite**: 100-prompt suite covering 6 domains and conversational noise invariance ([`test/eval-holdout.test.js`](test/eval-holdout.test.js)).
77
+ * **📊 RouterArena Benchmark Candidate**: Scored **77.93** in official GitHub Actions CI evaluation under [RouteWorks PR #169](https://github.com/RouteWorks/RouterArena/pull/169) (Live published leaderboard led by Paix2 at 77.63; candidate awaiting merge).
78
+ * **🛑 Native AbortSignal Support**: First-class timeout and cancellation management.
79
+ * **📦 Universal Distribution**: Full TypeScript types, ESM, and CommonJS builds.
80
+
81
+ ---
82
+
83
+ ## 📊 Multi-Benchmark Performance & Evaluation Matrix
84
+
85
+ `krusch-cascade-router` has been evaluated across standard routing benchmark harnesses:
86
+
87
+ | Benchmark Suite | Sponsoring Organization / Publication | Benchmark Scope | Baseline Comparison | Krusch Cascade Router Evaluation | Primary Metric | Cost Reduction vs Frontier | Routing Overhead |
88
+ |:---|:---|:---|:---|:---|:---:|:---:|:---:|
89
+ | **1. RouterArena** | RouterArena Consortium (Rice Univ) | 8,400 Benchmark Queries (+3,236 Optimality + 420 Robustness) | Multi-Model Frontier Pool | **Official PR #169 Bot Eval**:<br>Workflow Score: **77.93**<br>Accuracy: **81.53%**<br>*(Official live #1: Paix2 @ 77.63)* | **77.93 (CI Bot)**<br>([Evaluated in PR #169](https://github.com/RouteWorks/RouterArena/pull/169)) | **$0.61 / 1K queries**<br>(vs $1.00 Orca, $4.10 NotDiamond) | < 0.15 ms<br>(6,600+ QPS) |
90
+ | **2. Integration Suite** | Real-World Developer Prompts | 100 Diverse Queries across 6 Domains | Multi-Model Pool | **Routing Precision: 100.0%**<br>Noise Invariance: **100.0%**<br>*(Classifier routing precision, not LLM output)* | **100.0% Routing**<br>(Classification test suite) | **~75% Savings**<br>vs Frontier Oracle | 0.02 ms<br>(50,000+ QPS) |
91
+ | **3. WithMartian RouterBench**<br>*(Offline Simulation)* | WithMartian (arXiv: 2403.12031) | 36,497 Real Inference Outcomes across 11 LLMs | Single-Model GPT-4 Oracle ($94.39 Total Cost) | **AIQ Score: 0.7200** (92.1% of Ceiling)<br>Frugal: 64.51% Acc @ $8.13<br>Balanced: 75.08% Acc @ $52.52 | **0.7200 AIQ Score**<br>(Offline Simulation) | **93.23% (Frugal)**<br>**56.29% (Balanced)** | 0.11 ms<br>(9,066 QPS) |
92
+ | **4. Google AutoMix**<br>*(Offline Simulation)* | Google Research & CMU (NeurIPS 2024) | 14,571 Validation Queries across 5 QA/RC Datasets | Speculative Cascade LLaMA-13B $\rightarrow$ LLaMA-70B | **CoQA Lift: +55.17%** (vs +43.68% POMDP)<br>**NarrativeQA: +17.45%** (vs +6.44% POMDP) | **+55.17% IBC Lift**<br>(Offline Simulation) | **82.40% on CoQA**<br>**68.39% on NarrativeQA** | 0.007 ms<br>(137,081 QPS) |
93
+ | **5. LMSYS RouteLLM**<br>*(Offline Simulation)* | LMSYS Org / UC Berkeley (arXiv: 2406.18665) | 10,000+ Battles across GSM8K, MT-Bench, MMLU | GPT-4 vs Mixtral / LLaMA-3 | **MT-Bench: 0.6027 APGR**<br>**GSM8K: 0.5602 APGR**<br>**MMLU: 0.5060 APGR** | **0.6027 APGR**<br>(Offline Simulation) | **50%–75% Savings**<br>at 95% Quality Retention | < 0.05 ms<br>(20,000+ QPS) |
94
+
95
+ > 🔍 **Full Technical Documentation & Methodology**: Detailed per-benchmark curves, domain breakdowns, and derivations are available in [`docs/BENCHMARK.md`](docs/BENCHMARK.md).
96
+ >
97
+ > 💡 **Methodology & Context Note on Benchmark Results**:
98
+ > The metrics reported in this evaluation matrix reflect offline simulation runs evaluating our modern 5-model specialist pool (`Qwen3-Coder-Next`, `deepseek-v4-flash`, `deepseek-v4-pro`, `gemini-3.1-flash-lite`, `qwen3-235b-a22b`) against standard public benchmark datasets and task queries.
99
+ >
100
+ > **Important Reproducibility Context**:
101
+ > - **Live Leaderboard Clarification**: As published on the official [RouteWorks/RouterArena live board](https://routeworks.github.io/leaderboard), **Paix2 is the official published #1 at 77.63**. Our candidate submission achieved **77.93 in official GitHub Actions CI evaluation under [PR #169](https://github.com/RouteWorks/RouterArena/pull/169)** awaiting maintainer review and should be treated as an unmerged candidate submission until officially merged.
102
+ > - **Reconstructed Simulation Methodology (Suites 3–5)**: RouterBench, AutoMix, and RouteLLM figures represent reconstructed offline simulations evaluating our specialist models on those public benchmark datasets against historical baseline oracles (e.g. GPT-4 vs LLaMA-13B from 2023/2024 literature). They are local simulations, NOT independent official leaderboard submissions to those platforms.
103
+ > - **Classifier Accuracy vs Generation Quality**: The 100% precision figure reported in the Developer Integration Suite measures *prompt domain routing classification* (ensuring code/math/trivia queries land on the correct model bucket), NOT generative correctness of the LLM responses.
104
+ >
105
+ > 🧪 **Audit Reproduction**: Run test suite:
106
+ > ```bash
107
+ > npm test
108
+ > ```
30
109
 
31
110
  ---
32
111
 
33
- ## 🧠 Architecture: How It Works
112
+ ### A. Live RouteWorks RouterArena Leaderboard
113
+
114
+ The public [RouteWorks/RouterArena](https://github.com/RouteWorks/RouterArena) leaderboard ranks published router implementations as follows:
115
+
116
+ | Rank | Router Implementation | Acc-Cost Score | Accuracy | Cost / 1K Queries | Robustness | Status |
117
+ |:---:|:---|:---:|:---:|:---:|:---:|:---:|
118
+ | 1 | **Paix2** | **77.63** | 79.69% | $0.2700 | 77.86% | Published (#1 on Live Board) |
119
+ | 2 | **KT-ModelRouter** | 76.28 | 78.14% | $0.2700 | 80.48% | Published |
120
+ | 3 | **Sqwish Router** | 76.21 | 79.76% | $0.7000 | 51.67% | Published |
121
+ | 4 | **Divyam** | 75.85 | 78.59% | $0.4800 | 98.33% | Published |
122
+ | 5 | **vLLM-SR** | 74.86 | 77.18% | $0.4200 | 67.62% | Published |
123
+ | 6 | **nadir-caliper** | 74.55 | 75.84% | $0.2200 | 79.76% | Published |
124
+ | 7 | **Azure-Model-Router (Microsoft)** | 70.42 | 72.94% | $0.7300 | 71.43% | Published |
125
+ | 8 | **RouterBench-MLP (Martian)** | 57.56 | 61.62% | $4.8300 | 80.00% | Published |
126
+ | 9 | **NotDiamond (Commercial)** | 57.29 | 60.83% | $4.1000 | 55.91% | Published |
127
+ | 10 | **RouteLLM (UC Berkeley)** | 48.07 | 47.04% | $0.2700 | 100.00% | Published |
128
+
129
+ #### Official Candidate Bot Runs (RouteWorks PR #169)
34
130
 
35
- 1. **Predictive Classifier**: Instantly evaluates the prompt's complexity via string heuristics (length, code blocks, complex cognitive verbs, or your `customRules`). If classified as complex, it routes directly to the heavy cloud model.
36
- 2. **Speculative Cascade**: If classified as simple, it streams the fast local edge model. It buffers and inspects the logprobs of the first N tokens. If the confidence (probability) dips below your configured threshold, it silently aborts the stream and falls back to the heavy cloud model.
131
+ Our candidate submission ([RouteWorks/RouterArena PR #169](https://github.com/RouteWorks/RouterArena/pull/169)) was evaluated directly by RouteWorks GitHub Actions CI workflows across the full 8,400-query benchmark dataset plus 420 robustness perturbations:
132
+
133
+ | Evaluation Run | Acc-Cost Score | Accuracy | Cost / 1K | Robustness | Evaluation Notes |
134
+ |:---|:---:|:---:|:---:|:---:|:---|
135
+ | **Run 1: Initial Full Eval** | 74.13 | 76.14% | $0.3700 | 93.10% | Baseline multi-model adapter |
136
+ | **Run 2: Cheaper 5-Model Pool** | 74.09 | 75.62% | $0.2700 | 94.05% | Shifted budget to cheaper flash endpoints |
137
+ | **Run 3: Heuristic Retune** | **77.93** | **81.53%** | **$0.6070** | **92.62%** | Disambiguated math operators & chess boundaries |
138
+
139
+ * **Official CI Bot Score**: **77.93** (Accuracy: 81.53%, Cost: $0.6070 / 1K, Robustness: 92.62%).
140
+ * **Status**: Submitted in [PR #169](https://github.com/RouteWorks/RouterArena/pull/169) and awaiting maintainer review. It is an unmerged candidate evaluation; the live leaderboard remains led by Paix2 at 77.63.
141
+ * **Optimal Selection (`Opt.Sel`) Note**: Across the official evaluation runs, `Opt.Sel` was ~0.05–0.07. `krusch-cascade-router` routes deterministically by domain specialization rather than attempting per-instance cost minimization, trading per-query oracle perfection for microsecond CPU latency and zero token overhead.
142
+
143
+ ---
144
+
145
+ ### B. WithMartian RouterBench Highlights (36,497 Queries)
146
+
147
+ * **0.7200 AIQ Score**: Captures **92.1% of the theoretical upper-bound ceiling (0.7818)**, comparing favorably to Martian's reference **RouterBench-MLP (0.6830)** and **RouterBench-KNN (0.6558)**.
148
+ * **Frugal Mode**: **64.51% Accuracy** at **$8.13 Total Cost** ($0.22/1k) — a **93.23% cost reduction vs GPT-4 ($94.39)**.
149
+ * **GSM-8K Math**: Delivers **62.70% accuracy at $4.34** vs GPT-4's $63.68 (**$59.34 direct savings**, a 93.18% reduction).
150
+ * **MBPP Code**: In Balanced Mode, matches GPT-4 quality within **0.24%** (68.38% vs 68.62%) while slashing cost by **78.5%**.
151
+
152
+ ---
153
+
154
+ ### C. Google AutoMix Highlights (NeurIPS 2024 / 14,571 Queries)
155
+
156
+ * **CoQA Benchmark**: **+55.17% IBC Lift** vs AutoMix POMDP (+43.68%) with **82.40% cost reduction** vs LLaMA-70B.
157
+ * **NarrativeQA Benchmark**: **+17.45% IBC Lift** vs AutoMix POMDP (+6.44%).
158
+ * **Zero Verification Overhead**: Heuristic classification avoids spending tokens on self-verification calls.
159
+ * **Speed**: Heuristic classification runs in microseconds on CPU vs multiple seconds for LLM-based verifiers.
160
+
161
+ ---
162
+
163
+ ## 🧠 Architecture: The L1 Pre-Router & Specialist Flow
37
164
 
38
165
  ```mermaid
39
166
  graph TD;
40
- A[Incoming Prompt] --> B{Heuristic Classifier};
41
- B -- Complex --> C[Heavy Cloud Model];
42
- B -- Simple --> D[Local Edge Model];
43
- D --> E{Evaluate Logprobs first N tokens};
44
- E -- Confidence >= Threshold --> F[Stream Edge Response];
45
- E -- Confidence < Threshold --> G[Abort Edge];
46
- G --> C;
167
+ A[Incoming Prompt] --> L1{Stage 1: L1 Pre-Router<br/>krusch-cascade-router<br/>&lt; 15µs CPU | $0.00};
168
+
169
+ %% Fast path branch
170
+ L1 -- "High-Confidence Deterministic Syntax<br/>(isFastPath: true)" --> FP[L1 Fast-Path Specialist Dispatch];
171
+ FP -- Code, SQL, Rust, React --> C1[Qwen3-Coder-Next];
172
+ FP -- STEM, Factual Science, Math --> C2[deepseek-v4-flash];
173
+ FP -- Reading Comp, Paragraph Truth --> C3[qwen3-235b-a22b];
174
+ FP -- Translation, Geography, Medicine --> C4[gemini-3.1-flash-lite];
175
+ FP -- Financial Statements, Formal Proofs --> C5[deepseek-v4-pro];
176
+
177
+ %% Reactive abort fallback
178
+ C1 -. Error / Logprob Abort .-> C5;
179
+ C2 -. Error / Logprob Abort .-> C5;
180
+ C3 -. Error / Logprob Abort .-> C5;
181
+ C4 -. Error / Logprob Abort .-> C5;
182
+
183
+ %% L2 fallback branch
184
+ L1 -- "Ambiguous / Unstructured Chat<br/>(suggestedAction: delegate_to_l2)" --> L2[Stage 2: L2 Semantic Layer<br/>RouteLLM / NotDiamond / Frontier Model];
47
185
  ```
48
186
 
49
187
  ---
50
188
 
189
+ ## 📖 Theoretical Foundations & Related Work
190
+
191
+ `krusch-cascade-router` draws on proven systems concepts and dynamic inference literature:
192
+
193
+ 1. **Sequential Model Cascading & Fallbacks** (*FrugalGPT; Chen et al., 2023, [arXiv:2305.05176](https://arxiv.org/abs/2305.05176)*):
194
+ - Establishes the sequential cascade principle: querying smaller/cheaper models first and escalating to frontier models only upon low confidence or failure.
195
+ 2. **Speculative Parallel Hedging** (*The Tail at Scale; Dean & Barroso, Communications of the ACM, 2013*):
196
+ - Rather than waiting sequentially for borderline queries, issuing hedged requests across models masks cascade latency and caps 99th-percentile response times.
197
+ 3. **Degenerative Token Loops & Repetition** (*The Curious Case of Neural Text Degeneration; Holtzman et al., ICLR 2020*):
198
+ - Autoregressive generation is prone to degenerate repetitive cycles. Monitoring sliding-window $n$-gram repetition allows aborting runaway loops mid-stream before consuming full output tokens.
199
+ 4. **Zero-Overhead vs. Learned Routing** (*RouterBench; Hu et al., 2024, [arXiv:2403.12031](https://arxiv.org/abs/2403.12031)* & *RouteLLM; Ong et al., 2024, [arXiv:2406.18665](https://arxiv.org/abs/2406.18665)*):
200
+ - Multi-LLM routing benchmarks show that while learned classifiers or LLM routers achieve high accuracy, they introduce 15–50ms embedding overhead or 500ms+ LLM latency. Fast heuristic gating provides sub-millisecond dispatch for distinct syntactic and domain signatures.
201
+
202
+ ---
203
+
51
204
  ## 📦 Installation
52
205
 
206
+ From npm:
53
207
  ```bash
54
208
  npm install krusch-cascade-router
55
209
  ```
56
210
 
57
- > **Note**: Requires Node.js 18+ for native fetch and `AbortSignal` support.
211
+ Or directly from GitHub:
212
+ ```bash
213
+ npm install github:kruschdev/krusch-cascade-router
214
+ ```
215
+
216
+ Or from local checkout:
217
+ ```bash
218
+ npm install ../path/to/krusch-cascade-router
219
+ ```
220
+
221
+ > **Requirement**: Node.js 18+ (utilizes native `fetch` and `AbortSignal`).
58
222
 
59
223
  ---
60
224
 
61
225
  ## 🚀 Quick Start Guide
62
226
 
227
+ ### Option A: 5-Model Specialist Router via OpenRouter (Recommended)
228
+
229
+ Instantiate a complete multi-specialist router using 5 specialized domain models routed directly through OpenRouter:
230
+
231
+ ```javascript
232
+ import { createMultiSpecialistRouter } from 'krusch-cascade-router';
233
+
234
+ // 1. Initialize with your OpenRouter API key (preset defaults or custom overrides)
235
+ const router = createMultiSpecialistRouter({
236
+ openrouterApiKey: process.env.OPENROUTER_API_KEY, // Defaults to process.env.OPENROUTER_API_KEY
237
+ openrouterReferer: 'https://my-app.com', // Optional attribution header
238
+ openrouterTitle: 'My App',
239
+ // Optional: override any specialist model to prevent catalog rot or route to preferred endpoints
240
+ // customModels: { code: 'qwen/qwen-2.5-coder-32b-instruct', reasoning_deep: 'deepseek/deepseek-r1' }
241
+ });
242
+
243
+ // 2. Dispatch queries - automatically routed to optimal domain specialist:
244
+ // - Code & Algorithms -> Qwen/Qwen3-Coder-Next
245
+ // - Chess & Spatial Games -> Qwen/Qwen3-Coder-Next
246
+ // - STEM & Factual Science -> deepseek/deepseek-v4-flash
247
+ // - Complex Proofs & Financial QA -> deepseek/deepseek-v4-pro
248
+ // - General Fast & Translation -> google/gemini-3.1-flash-lite
249
+ // - Reading Comprehension & Verification -> qwen/qwen3-235b-a22b-2507
250
+ const res = await router.chat("Write an algorithm in Rust to detect cycles in a directed graph");
251
+ console.log(`Routed to: ${res.routedTo}`); // 'code' (Qwen/Qwen3-Coder-Next)
252
+ console.log(res.text);
253
+ ```
254
+
255
+ ### Option B: L1 Pre-Router Fast-Path Gate (In Front of Any LLM Pipeline)
256
+
257
+ If your architecture already uses an L2 neural router (e.g. RouteLLM, NotDiamond) or a frontier model, use `krusch-cascade-router` as an **in-memory L1 pre-filter**. It intercepts 70–80% of structured agent traffic in CPU microseconds without paying the latency or token tax of a neural classifier:
258
+
259
+ ```javascript
260
+ import { classifyPreRoute } from 'krusch-cascade-router';
261
+
262
+ async function dispatchAgentPrompt(prompt) {
263
+ // 1. L1 Pre-Check in <15 microseconds ($0.00 cost, 0 tokens)
264
+ const preRoute = classifyPreRoute(prompt);
265
+
266
+ if (preRoute.isFastPath) {
267
+ console.log(`⚡ L1 Fast-Path Hit -> Dispatching to specialist: ${preRoute.role}`);
268
+ // Bypass expensive routers and call the dedicated specialist directly:
269
+ return callSpecialistModel(preRoute.role, prompt);
270
+ }
271
+
272
+ // 2. L1 Miss: Prompt is unstructured / ambiguous conversational chat
273
+ console.log(`🔍 L1 Miss -> Delegating to L2 Neural Router or Frontier Model`);
274
+ return callSecondaryNeuralRouter(prompt); // e.g. RouteLLM, NotDiamond, or Claude 3.7
275
+ }
276
+ ```
277
+
278
+ ### Option C: L1 Fast-Path + L2 Neural Semantic Router Cascade
279
+
280
+ When an incoming prompt misses the Stage-0/L1 syntactic gate (`isFastPath: false`), `CascadeRouter` can query an **L2 Neural Semantic Router** (such as [`krusch-context-mcp`](https://github.com/kruschdev/krusch-context-mcp) or RouteLLM) to dynamically resolve the optimal domain specialist model rather than falling back to a generic default:
281
+
282
+ ```javascript
283
+ import {
284
+ CascadeRouter,
285
+ createCentroidSemanticRouter,
286
+ createContextMcpRouter
287
+ } from 'krusch-cascade-router';
288
+
289
+ // Approach 1: In-process L2 Neural Router via local Ollama (bge-large, 1024d)
290
+ const l2OllamaRouter = createCentroidSemanticRouter({
291
+ ollamaUrl: 'http://localhost:11434',
292
+ embedModel: 'bge-large'
293
+ });
294
+
295
+ // Approach 2: Direct adapter to krusch-context-mcp server tool
296
+ // const l2McpRouter = createContextMcpRouter((name, args) => mcpClient.callTool({ name, arguments: args }));
297
+
298
+ const router = new CascadeRouter({
299
+ fastModel: { model: 'gemini-3.1-flash-lite' },
300
+ heavyModel: { model: 'deepseek-v4-pro' },
301
+ specialistModels: {
302
+ code: { model: 'Qwen/Qwen3-Coder-Next' },
303
+ reasoning_deep: { model: 'deepseek/deepseek-v4-pro' },
304
+ factual_stem: { model: 'deepseek/deepseek-v4-flash' }
305
+ },
306
+ // 🧠 L2 Neural Semantic Router: queried only on L1 pre-router misses
307
+ l2Router: l2OllamaRouter
308
+ });
309
+
310
+ // 1. Structured syntax -> Bypasses L2 entirely (<15µs L1 hit on CPU for $0.00)
311
+ await router.chat("```python\ndef fib(n): pass\n```");
312
+
313
+ // 2. Unstructured/ambiguous query -> Evaluated by L2 in ~20ms, routed to optimal specialist
314
+ await router.chat("Can you explain why the event loop hangs during concurrent queue drain?");
315
+ ```
316
+
317
+ ### Option D: 2-Model Binary Edge Cascade
318
+
319
+ Pair a local edge model (Ollama, vLLM) with a heavy cloud model fallback:
320
+
63
321
  ```javascript
64
322
  import { CascadeRouter } from 'krusch-cascade-router';
65
323
 
66
- // 1. Initialize the router with your edge and cloud models
67
324
  const router = new CascadeRouter({
68
325
  fastModel: {
69
326
  url: 'http://localhost:11434/v1/chat/completions',
70
- model: 'qwen2.5:3b' // Edge node tag resolution
327
+ model: 'qwen2.5:3b' // Local edge model
71
328
  },
72
329
  heavyModel: {
73
330
  apiKey: process.env.GEMINI_API_KEY,
74
- model: 'gemini-2.5-pro',
331
+ model: 'gemini-2.5-flash',
75
332
  provider: 'gemini'
76
333
  },
77
- cascadeThreshold: 0.85, // Abort if average probability of first 5 tokens is < 85%
78
- tokensToEvaluate: 5
334
+ cascadeThreshold: 0.85, // Fallback if initial token probability < 85%
335
+ tokensToEvaluate: 5, // Tokens to inspect before committing
336
+ speculativeBranching: true // Pre-warm heavy model on borderline prompts
79
337
  });
80
338
 
81
- // 2. Send a chat request
82
- const response = await router.chat("Write a complex architectural plan...");
83
-
84
- // 3. Check where it was routed
85
- console.log(`Routed to: ${response.routedTo}`);
339
+ const response = await router.chat("Explain the architecture of distributed raft consensus...");
340
+ console.log(`Routed to: ${response.routedTo}`); // 'fast' | 'heavy'
86
341
  console.log(response.text);
87
342
  ```
88
343
 
344
+ ### Option D: Future-Proofing & Custom Specialists
345
+
346
+ The 5 default models (`gemini-3.1-flash-lite`, `deepseek-v4-flash`, `Qwen3-Coder-Next`, `deepseek-v4-pro`, `qwen3-235b-a22b`) are an **empirical starter preset**, not a hardcoded lock-in. As OpenRouter models evolve, you can easily swap models, update token pricing, or inject custom domain regexes:
347
+
348
+ ```javascript
349
+ import { createMultiSpecialistRouter } from 'krusch-cascade-router';
350
+
351
+ const router = createMultiSpecialistRouter({
352
+ openrouterApiKey: process.env.OPENROUTER_API_KEY,
353
+ // 1. Swap or upgrade specialist models (strings or full ModelConfig objects)
354
+ customModels: {
355
+ code: 'anthropic/claude-3.7-sonnet',
356
+ reasoning_deep: 'openai/o3-mini',
357
+ factual_stem: {
358
+ model: 'meta-llama/llama-3.3-70b-instruct',
359
+ provider: 'openrouter',
360
+ costPerMillionInputTokens: 0.12,
361
+ costPerMillionOutputTokens: 0.30
362
+ }
363
+ },
364
+ // 2. Inject custom domain regex rules evaluated before default heuristics
365
+ classifier: {
366
+ customSpecialistRules: [
367
+ { role: 'reasoning_deep', pattern: /\b(?:legal compliance|gdpr audit|sec filing)\b/i },
368
+ { role: 'code', pattern: /\b(?:terraform plan|ansible playbook|helm chart)\b/i }
369
+ ]
370
+ },
371
+ // 3. Optional local edge model for low-priority / background batch jobs
372
+ backgroundModel: {
373
+ url: 'http://localhost:11434/v1/chat/completions',
374
+ model: 'qwen2.5:3b',
375
+ costPerMillionInputTokens: 0,
376
+ costPerMillionOutputTokens: 0
377
+ }
378
+ });
379
+ ```
380
+
89
381
  ---
90
382
 
91
- ## 🛠️ Advanced Usage
383
+ ## 🛠️ Advanced Features
384
+
385
+ ### 1. L1 Pre-Router Gate (`classifyPreRoute`)
92
386
 
93
- ### Custom Heuristic Rules (`customRules`)
94
- You can inject your own detection logic to fine-tune what goes directly to the cloud model:
387
+ Evaluate prompts with detailed metadata on whether to bypass or delegate to L2:
95
388
 
96
389
  ```javascript
97
- const router = new CascadeRouter({
98
- // ...models config
99
- customRules: [
100
- (prompt) => prompt.includes('PostgreSQL'), // Always route DB questions to cloud
101
- (prompt) => prompt.length > 2000 // Override default length heuristics
102
- ]
103
- });
390
+ import { classifyPreRoute } from 'krusch-cascade-router';
391
+
392
+ const res = classifyPreRoute("Write a SQL query to calculate user churn");
393
+ console.log(res);
394
+ // {
395
+ // isFastPath: true,
396
+ // role: 'code',
397
+ // confidence: 'high',
398
+ // complexityScore: 0.20,
399
+ // suggestedAction: 'dispatch_specialist'
400
+ // }
401
+
402
+ const chat = classifyPreRoute("How are you feeling today?");
403
+ console.log(chat);
404
+ // {
405
+ // isFastPath: false,
406
+ // role: 'factual_stem',
407
+ // confidence: 'unstructured',
408
+ // complexityScore: 0.05,
409
+ // suggestedAction: 'delegate_to_l2'
410
+ // }
104
411
  ```
105
412
 
106
- ### Timeouts and AbortSignals
107
- Native integration with `AbortSignal` for graceful timeout handling:
413
+ ### 2. Specialist Domain Classification
414
+
415
+ Classify incoming queries into domain roles deterministically in under 15 microseconds:
416
+
417
+ ```javascript
418
+ import { classifySpecialistRole } from 'krusch-cascade-router';
419
+
420
+ classifySpecialistRole("def quicksort(arr): ..."); // 'code'
421
+ classifySpecialistRole("Options: \nA. Alpha\nB. Beta"); // 'factual_stem'
422
+ classifySpecialistRole("Evaluate FEN: rnbqkbnr/pppppppp/..."); // 'games_spatial'
423
+ classifySpecialistRole("Prove that every planar graph is 4-colorable"); // 'reasoning_deep'
424
+ ```
425
+
426
+ ### 3. Knowledge Boundary Detection
427
+
428
+ Closed-world tasks (e.g. arithmetic, code formatting, unit conversion, translation) are actively degraded by large model context pollution. You can invoke the boundary classifier directly:
429
+
430
+ ```javascript
431
+ import { detectKnowledgeBoundary } from 'krusch-cascade-router';
432
+
433
+ detectKnowledgeBoundary("Calculate 42 * 18 / 3"); // 'closed'
434
+ detectKnowledgeBoundary("Translate this sentence to French: Good morning"); // 'closed'
435
+ detectKnowledgeBoundary("Analyze the ethical dilemmas in autonomous driving"); // 'open'
436
+ ```
437
+
438
+ ### 3. Continuous Complexity Scoring
439
+
440
+ ```javascript
441
+ import { evaluateComplexityScore } from 'krusch-cascade-router';
442
+
443
+ const score = evaluateComplexityScore("Compare Postgres vs SQLite tradeoffs for edge devices");
444
+ // Returns continuous float in [0.0, 1.0] (e.g., 0.42 -> triggers speculative branching)
445
+ ```
446
+
447
+ ### 4. Native AbortSignal & Timeouts
108
448
 
109
449
  ```javascript
110
450
  const controller = new AbortController();
111
- setTimeout(() => controller.abort(), 10000); // 10s timeout
451
+ setTimeout(() => controller.abort(), 8000); // 8-second SLA
112
452
 
113
453
  try {
114
- const response = await router.chat("Analyze this dataset", {
454
+ const response = await router.chat("Analyze telemetry logs", undefined, {
115
455
  signal: controller.signal
116
456
  });
117
457
  } catch (err) {
118
458
  if (err.name === 'AbortError') {
119
- console.log('Request was timed out or aborted manually.');
459
+ console.log('Request SLA exceeded.');
120
460
  }
121
461
  }
122
462
  ```
123
463
 
124
- ---
125
-
126
- ## 📚 API Reference
464
+ ### 5. Telemetry Events & Callbacks
127
465
 
128
- ### `new CascadeRouter(config)`
129
-
130
- | Property | Type | Description |
131
- |---|---|---|
132
- | `fastModel` | `ModelConfig` | Configuration for your fast, local edge model (e.g. Ollama). |
133
- | `heavyModel` | `ModelConfig` | Configuration for your heavy cloud fallback (e.g. Gemini, OpenAI). |
134
- | `cascadeThreshold` | `number` | Confidence probability (0.0 to 1.0). If logprobs dip below this, it cascades. |
135
- | `tokensToEvaluate` | `number` | How many tokens to buffer before making the speculative decision. |
136
- | `customRules` | `Array<(prompt: string) => boolean>` | *(Optional)* Array of heuristic functions to override complex prompt detection. |
466
+ ```javascript
467
+ const router = new CascadeRouter({
468
+ // ...config
469
+ onEvent: (event, meta) => {
470
+ // Events: 'route_specialist' | 'route_l2_semantic' | 'route_fast' | 'route_heavy' | 'cascade_triggered' |
471
+ // 'speculative_branch_hedged' | 'repetition_loop_triggered' | 'entropy_collapse_triggered'
472
+ console.log(`[Router Telemetry] ${event}`, meta);
473
+ }
474
+ });
475
+ ```
137
476
 
138
- ### `router.chat(prompt, options?)`
477
+ ---
139
478
 
140
- | Parameter | Type | Description |
141
- |---|---|---|
142
- | `prompt` | `string` | The user's input prompt. |
143
- | `options` | `ChatOptions` | *(Optional)* Options like `{ signal: AbortSignal }`. |
479
+ ## 📚 API Reference
144
480
 
145
- **Returns:** `Promise<{ text: string, routedTo: 'fast' | 'heavy' }>`
481
+ ### `createMultiSpecialistRouter(options?: MultiSpecialistRouterOptions): CascadeRouter`
482
+
483
+ Factory function configuring the 5 specialist models, routing through OpenRouter.
484
+
485
+ | Option | Type | Default | Description |
486
+ |---|---|:---:|---|
487
+ | `openrouterApiKey` | `string` | `process.env.OPENROUTER_API_KEY` | API key for OpenRouter. |
488
+ | `customModels` | `Partial<Record<SpecialistRole, string \| ModelConfig>>` | `undefined` | Custom model ID strings or full `ModelConfig` objects overriding default specialists. |
489
+ | `classifier` | `ClassifierOptions` | `undefined` | Custom options, including `customSpecialistRules` and `customRules`. |
490
+ | `l2Router` | `SemanticRouterL2` | `undefined` | Optional L2 Neural Semantic Router invoked dynamically when L1 fast-path misses. |
491
+ | `backgroundModel` | `ModelConfig` | `undefined` | Optional model for low-priority/background batch jobs. |
492
+ | `openrouterReferer` | `string` | `undefined` | Optional `HTTP-Referer` header for rankings. |
493
+ | `openrouterTitle` | `string` | `undefined` | Optional `X-Title` header for rankings. |
494
+ | `cascadeThreshold` | `number` | `0.85` | Logprob confidence threshold for cascading. |
495
+ | `tokensToEvaluate` | `number` | `5` | Tokens to buffer and evaluate for initial confidence. |
496
+ | `maxRepetitiveTokens` | `number` | `4` | Threshold for degenerate repetition and cyclic loop detection. |
497
+ | `speculativeBranching` | `boolean` | `false` | Enable Second Thought speculative hedging. |
498
+ | `prunePreRouting` | `boolean` | `false` | Strips conversational filler and whitespace before length evaluation. |
499
+ | `onEvent` | `Function` | `undefined` | Telemetry callback for observability. |
500
+
501
+ ### `new CascadeRouter(config: RouterConfig)`
502
+
503
+ | Property | Type | Default | Description |
504
+ |---|---|:---:|---|
505
+ | `fastModel` | `ModelConfig` | *Required* | Fast edge model config (e.g., local Ollama, vLLM, `gemini-3.1-flash-lite`). |
506
+ | `heavyModel` | `ModelConfig` | *Required* | Heavy cloud fallback config (e.g., `deepseek-v4-pro`, GPT-4o). |
507
+ | `specialistModels` | `Partial<Record<SpecialistRole, ModelConfig>>` | `undefined` | Map of domain specialist models. |
508
+ | `l2Router` | `SemanticRouterL2` | `undefined` | Optional L2 Neural Semantic Router hook (`(prompt, context) => Promise<SemanticRouteResult>`). |
509
+ | `openrouterApiKey` | `string` | `undefined` | Global OpenRouter API key for specialist models. |
510
+ | `openrouterReferer` | `string` | `undefined` | Global HTTP-Referer header for OpenRouter calls. |
511
+ | `openrouterTitle` | `string` | `undefined` | Global X-Title header for OpenRouter calls. |
512
+ | `backgroundModel` | `ModelConfig` | `undefined` | Optional model for low-priority/background batch jobs. |
513
+ | `cascadeThreshold` | `number` | `0.85` | Confidence cutoff probability (`0.0` to `1.0`). |
514
+ | `tokensToEvaluate` | `number` | `5` | Tokens to buffer and evaluate for initial confidence. |
515
+ | `maxRepetitiveTokens` | `number` | `4` | Threshold for degenerate repetition and cyclic loop detection. |
516
+ | `speculativeBranching` | `boolean` | `false` | Enables Second Thought parallel hedging for borderline prompts. |
517
+ | `prunePreRouting` | `boolean` | `false` | Strips conversational filler and whitespace before length evaluation. |
518
+ | `classifier` | `ClassifierOptions` | `undefined` | Custom options, `customSpecialistRules`, and `customRules` regexes. |
519
+ | `onEvent` | `Function` | `undefined` | Telemetry callback for observability. |
146
520
 
147
521
  ---
148
522
 
149
- ## 🤝 Contributing
150
-
151
- We welcome contributions! Please follow the established homelab conventions:
152
- - Library code must NEVER use `console.warn` or `console.log` directly. Route diagnostics through callback options (`onEvent` pattern).
153
- - Ensure your `AbortSignal` listeners use `{ once: true }` to prevent leaks.
154
- - Run tests via `npm test` before submitting PRs.
155
-
156
523
  ## 📄 License
157
524
 
158
525
  MIT License © 2026 kruschdev