# cortiq-dsh-llm-router 🧠✨

**Your LLMs on autopilot.** One key — every prompt is automatically dispatched to the best model.

> Stop guessing which model to pick. Just type — the plugin figures out where to send each request.

---

## 🚀 Quick Start (1 minute)

```bash
dsh plugin add cortiq-dsh-llm-router
# Go to Settings → Models → Cortiq Router, paste your key
# Then pick "Cortiq Router · Auto" in the chat model selector
```

**Done.** The plugin handles everything from here.

> **One prerequisite:** the router picks *among the models your other provider
> plugins already serve* (e.g. `llm-deepseek`). Keep at least one of them
> configured — the router never talks to a model vendor itself.

---

## 🎁 Free Trial

**Get a free key for 1 month** — no payment required.

👉 [allaigate.com](https://api.allaigate.com/) — sign up and get a `cortiq_…` key instantly.

No promo code needed. After the trial, plans start at just **$1/month**.

---

## 💰 What does it cost?

| Without plugin | With plugin |
|----------------|-------------|
| All requests go to expensive models | Simple requests → cheap model |
| Overpay 10–50× | Save up to 90% |
| Manual model selection every time | Fully automatic |

---

## 🎯 What it does

The plugin is a **smart dispatcher** for your LLMs. It reads every prompt, understands what you're asking, and routes it to the right model.

### Live example

You type: *"Write a Python function to reverse a linked list"*

| Without plugin | With plugin |
|---|---|
| 🤷‍♂️ Have to pick a model yourself | 🔍 **Router:** "This is code, low complexity (0.29)" |
| 🎲 Guess: DeepSeek V4 Pro ($) | 🧠 **Rule:** code @ low → fast model |
| Response in 3s, paid $0.01 | ⚡ Response in 0.5s, free |

But: *"Implement a distributed consensus algorithm"*

| Without plugin | With plugin |
|---|---|
| 🤷‍♂️ Guess again | 🔍 **Router:** "This is code, high complexity (0.78)" |
| Maybe Flash is enough? | 🚀 **Escalation:** hard request → powerful model |
| Response might be bad | ✅ Strong model handles it well |

---

## ⚙️ What can you configure?

### Complexity thresholds

```yaml
complexityBands:
  low:   0.35    # score ≤ 0.35 → simple task
  medium: 0.65   # ≤ 0.65 → medium, > 0.65 → hard
```

### Which models at which complexity

```yaml
globalTiers:
  low:    [deepseek-v4-flash]           # simple → fast & cheap
  medium: [deepseek-v4-pro]             # medium → more powerful
  high:   [deepseek-v4-pro]             # hard → strongest
```

### Per-task rules

```yaml
taskRules:
  code:
    low:  [deepseek-v3-chat]            # simple code → fast model
    high: [deepseek-v4-pro]             # complex code → powerful model
  translation: [deepseek-v3-chat]       # simple form: same model at all tiers
  creative-writing:
    low:  [deepseek-v4-flash]
    high: [deepseek-v4-pro]
```

---

## 🎮 Who is this for?

| You | Why you need it |
|---|---|
| **AI agent developers** | Your agent picks the right model automatically, saving tokens |
| **Freelancers / solo devs** | Save on API costs without sacrificing quality |
| **Teams / startups** | One key, automatic routing, full transparency |
| **Enthusiasts** | Smart routing for $1/month — no headache |

---

## 📊 Real-world accuracy

We ran 8 different prompt types through the live allaigate router:

```
Prompt                                                    Task              Conf    → Routed To
─────────────────────────────────────────────────────────────────────────────────────────────
Write a Python function to reverse a linked list          code              0.991   fast model ✓
Solve quadratic equation x² - 5x + 6 = 0                  math              0.980   medium model
Translate to French: Hello world                          translation       0.988   fast model ✓
Write a poem about AI consciousness                       creative-writing  0.950   fast model ✓
What is the capital of France?                            qa                0.998   medium model
Summarize: The quick brown fox...                         summarization     0.980   medium model
Extract date and price from invoice                       extraction        0.997   medium model
How are you doing today?                                  chitchat          1.000   medium model
```

**8/8 — all task types correctly identified.**  
✓ = task rule applied → model chosen intentionally

---

## 🔄 How it works

```
You: "write code to reverse a list"
    │
    ▼
┌─────────────────────────────┐
│ 1. Text extraction           │ ← only last_user (PII stays local)
└──────────┬──────────────────┘
           │ POST /v1/route
           ▼
┌─────────────────────────────┐
│ 2. Semantic router           │ ← router.allaigate.com
│    task=code, complexity=low │
└──────────┬──────────────────┘
           │
           ▼
┌─────────────────────────────┐
│ 3. Routing table             │ ← your configuration
│    code @ low → flash        │
│    ↳ fallback → flash/pro    │
└──────────┬──────────────────┘
           │ invoke
           ▼
┌─────────────────────────────┐
│ 4. Delegated to the provider │
│    plugin that serves it     │
└─────────────────────────────┘
```

---

## 🎛 Picking a policy per chat

The model picker lists four entries. All of them route; the last three pin the
policy profile for that conversation, so you don't have to open settings:

| Entry | What it does |
|---|---|
| **Auto** | Routes using the profile configured in settings |
| **Auto · cost saver** | Prefers the cheap end of every chain |
| **Auto · balanced** | The middle ground |
| **Auto · quality first** | Escalates sooner to the strong models |

---

## ⚙️ Settings UI

The plugin adds its own **Cortiq Router** section to the harness settings, in
every language it ships:

| What you get there | |
|---|---|
| **Classifier key** | paste it once; stored through the credentials service, with a configured / not-configured badge |
| **Endpoint & behaviour** | classifier URL, policy profile, what gets classified, character cap, timeout, decision logging |
| **Complexity bands** | where low / medium / high sit on the 0…1 score, with a low-below-medium check |
| **Model chains** | the per-tier chains and the fallback model |
| **Per-task rules** | a table of task × low / medium / high / any, with add and remove |

> It is a section of its own, not a card inside **Models**. The Models page
> picks its provider editor by namespace and offers third-party providers only
> a note pointing at `settings.yaml`, with Apply disabled — so the plugin
> registers through the same `settings.section` slot the Models page itself uses.

---

## 🌍 Languages

The plugin ships its own copy in **7 languages** — 🇬🇧 English · 🇷🇺 Русский ·
🇨🇳 中文 · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇹🇷 Türkçe — selected by the
`language` setting:

```yaml
llm-cortiq-router:
  language: auto   # auto | en | ru | zh | de | fr | es | tr
```

`auto` follows the harness UI language. Note that the dsh browser client itself
ships only English and Chinese, so `auto` resolves to one of those two; pick any
of the other five explicitly here to use it.

Translated: the entries this provider shows in the model picker, and the message
shown when no candidate model could serve a call — the strings a provider plugin
actually puts in front of you. Log lines stay English: they are diagnostics meant
for issues and `grep`.

---

## 📦 Installation

```bash
# From DSH plugin store
dsh plugin add cortiq-dsh-llm-router

# Or via npm
npm install cortiq-dsh-llm-router
```

Or add to your `cordis.patch.yml`:

```yaml
- insert:
    - id: llm-cortiq-router
      name: 'cortiq-dsh-llm-router'
```

## 🔑 Get Your Key

1. Open **[allaigate.com](https://api.allaigate.com/)**
2. Sign up — get a **free 1-month key** instantly
3. Copy your key (`cortiq_…`)
4. In DSH: **Settings → Models → Cortiq Router** → paste your key

Or set the environment variable:
```bash
export CORTIQ_ROUTER_KEY=cortiq_your_key_here
```

---

## 💡 Tips

- **Start with defaults** — they're sensible and work out of the box; the
  classifier lives at `router.allaigate.com`, and `routerUrl` points a
  self-hosted deployment somewhere else
- **Add per-task rules** for tasks that matter most to you
- **Tweak complexityBands** to fine-tune when a request is considered "hard"
- **Watch the log** — with `echoRouting` on (the default), every call prints
  `task=… tier=… score=… → provider/model`, so you can see what it chose
- **Chains survive a missing key** — a candidate whose provider refuses the
  call (no credential, no adapter, unknown model) is skipped and the next one
  answers; only a provider that already started streaming keeps the call
- **Name a route explicitly** — a candidate written as `provider:model`
  (e.g. `deepseek-official:deepseek-v4-pro`) skips catalog lookup entirely

---

## 📄 License

MIT — do whatever you want.

---

**One key. No guessing. Every request goes to the best model.** 🚀