mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
docs: close critical documentation gaps (ACP, router strategies, APIs, compression) (#3438)
Integrated into release/v3.8.17
This commit is contained in:
@@ -6,6 +6,8 @@ lastUpdated: 2026-05-13
|
||||
|
||||
# OmniRoute Auto-Combo Engine
|
||||
|
||||
> **For Users**: Looking for a quick start? See the [Auto-Combo User Guide](../getting-started/AUTO-COMBO-GUIDE.md) for simple explanations and examples.
|
||||
|
||||
> Self-managing model chains with adaptive scoring + zero-config auto-routing
|
||||
|
||||
## Zero-Config Auto-Routing (`auto/` prefix)
|
||||
@@ -107,11 +109,11 @@ Four pre-defined weight profiles in `open-sse/services/autoCombo/modePacks.ts`.
|
||||
|
||||
| Factor | ship-fast | cost-saver | quality-first | offline-friendly |
|
||||
| :----------- | :-------- | :--------- | :------------ | :--------------- |
|
||||
| quota | 0.15 | 0.15 | 0.10 | **0.40** |
|
||||
| health | 0.30 | 0.20 | 0.20 | 0.30 |
|
||||
| costInv | 0.05 | **0.40** | 0.05 | 0.10 |
|
||||
| latencyInv | **0.35** | 0.05 | 0.05 | 0.05 |
|
||||
| taskFit | 0.10 | 0.10 | **0.40** | 0.00 |
|
||||
| quota | 0.14 | 0.14 | 0.10 | **0.37** |
|
||||
| health | 0.28 | 0.19 | 0.18 | 0.28 |
|
||||
| costInv | 0.05 | **0.37** | 0.05 | 0.10 |
|
||||
| latencyInv | **0.32** | 0.05 | 0.05 | 0.05 |
|
||||
| taskFit | 0.10 | 0.10 | **0.37** | 0.00 |
|
||||
| stability | 0.00 | 0.05 | 0.15 | 0.10 |
|
||||
| tierPriority | 0.05 | 0.05 | 0.05 | 0.05 |
|
||||
|
||||
@@ -119,10 +121,10 @@ Notes:
|
||||
|
||||
- `tierAffinity` and `specificityMatch` are not set in mode packs — `calculateScore()` treats them as `?? 0` when absent.
|
||||
- Each pack's emphasis at a glance:
|
||||
- **ship-fast** → latencyInv 0.35 + health 0.30 (low-latency, healthy connections)
|
||||
- **cost-saver** → costInv 0.40 (cheapest tokens win)
|
||||
- **quality-first** → taskFit 0.40 + stability 0.15 (best model for the task, consistent)
|
||||
- **offline-friendly** → quota 0.40 + health 0.30 (max headroom regardless of speed/cost)
|
||||
- **ship-fast** → latencyInv 0.32 + health 0.28 (low-latency, healthy connections)
|
||||
- **cost-saver** → costInv 0.37 (cheapest tokens win)
|
||||
- **quality-first** → taskFit 0.37 + stability 0.15 (best model for the task, consistent)
|
||||
- **offline-friendly** → quota 0.37 + health 0.28 (max headroom regardless of speed/cost)
|
||||
|
||||
## All Routing Strategies
|
||||
|
||||
@@ -205,6 +207,227 @@ Persisted `strategy: "auto"` combos can set `config.routerStrategy` (or legacy
|
||||
cost SLOs
|
||||
- `lkgp` — last known good provider first
|
||||
|
||||
### Router strategies in detail
|
||||
|
||||
The auto-combo engine exposes 5 pluggable **RouterStrategy** implementations that
|
||||
you can swap via `config.routerStrategy` (or the legacy `config.auto.routerStrategy`).
|
||||
Each strategy picks one provider from the candidate pool, given a `RoutingContext`
|
||||
(task type, tool/vision hints, token estimate, optional SLA policy, optional
|
||||
last-known-good provider).
|
||||
|
||||
#### 1. `rules` (default) — 6-factor weighted scoring
|
||||
|
||||
Wraps the existing scoring engine. Filters out `OPEN` circuit-breaker
|
||||
candidates, then runs `scorePool()` with the current task type and `getTaskFitness()`,
|
||||
picking the top-scoring provider.
|
||||
|
||||
```ts
|
||||
class RulesStrategyImpl implements RouterStrategy {
|
||||
readonly name = "rules";
|
||||
readonly description =
|
||||
"6-factor weighted scoring: quota, health, cost, latency, taskFit, stability";
|
||||
|
||||
select(pool, context) {
|
||||
const eligible = pool.filter((c) => c.circuitBreakerState !== "OPEN");
|
||||
const ranked = scorePool(eligible.length > 0 ? eligible : pool, context.taskType, undefined, getTaskFitness);
|
||||
return { provider: ranked[0].provider, /* ... */ };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**When to use**: Default. Use when you want a balanced trade-off across all signals.
|
||||
|
||||
**Alias**: `rules` (no alias)
|
||||
|
||||
---
|
||||
|
||||
#### 2. `cost` / `eco` — cheapest healthy provider
|
||||
|
||||
Sorts the candidate pool by `costPer1MTokens` (ascending) and picks the cheapest.
|
||||
Filters out `OPEN` candidates first.
|
||||
|
||||
```ts
|
||||
class CostStrategyImpl implements RouterStrategy {
|
||||
readonly name = "cost";
|
||||
readonly description = "Always selects cheapest available provider";
|
||||
|
||||
select(pool, context) {
|
||||
const healthy = pool.filter((c) => c.circuitBreakerState !== "OPEN");
|
||||
const sorted = [...healthy].sort((a, b) => a.costPer1MTokens - b.costPer1MTokens);
|
||||
return { provider: sorted[0].provider, /* ... */ };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**When to use**: Cost-sensitive workloads, batch processing, or background jobs.
|
||||
|
||||
**Aliases**: `cost`, `eco`
|
||||
|
||||
---
|
||||
|
||||
#### 3. `latency` / `fast` — lowest p95 latency with reliability penalty
|
||||
|
||||
Sorts by `p95LatencyMs + (errorRate * 1000)`. The error-rate penalty ensures
|
||||
unreliable providers are ranked lower even if their nominal latency is low.
|
||||
|
||||
```ts
|
||||
class LatencyStrategyImpl implements RouterStrategy {
|
||||
readonly name = "latency";
|
||||
readonly description = "Prioritizes lowest p95 latency with reliability weighting";
|
||||
|
||||
select(pool, context) {
|
||||
const healthy = pool.filter((c) => c.circuitBreakerState !== "OPEN");
|
||||
const sorted = [...healthy].sort((a, b) =>
|
||||
(a.p95LatencyMs + a.errorRate * 1000) - (b.p95LatencyMs + b.errorRate * 1000)
|
||||
);
|
||||
return { provider: sorted[0].provider, /* ... */ };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**When to use**: Latency-sensitive workloads like real-time chat, autocomplete, or
|
||||
interactive coding assistants.
|
||||
|
||||
**Aliases**: `latency`, `fast`
|
||||
|
||||
---
|
||||
|
||||
#### 4. `sla-aware` / `sla` — latency/error/cost SLO compliance
|
||||
|
||||
Scores each candidate by how well it satisfies the configured SLO policy:
|
||||
|
||||
| Factor | Weight | Formula |
|
||||
|--------|--------|---------|
|
||||
| Latency score | 35% | `threshold / max(value, ε)` |
|
||||
| Error score | 35% | `threshold / max(value, ε)` |
|
||||
| Health score | 15% | `1.0` (CLOSED) / `0.5` (HALF_OPEN) / `0.0` (OPEN) |
|
||||
| Cost score | 10% | `threshold / max(value, ε)` or inverse normalized |
|
||||
| Stability score | 5% | inverse normalized latency stddev |
|
||||
|
||||
When `hardConstraints: true`, candidates are sorted primarily by **violation score**
|
||||
(how far they exceed any SLO), then by composite score. Otherwise it's just
|
||||
the composite score.
|
||||
|
||||
```ts
|
||||
class SLAStrategyImpl implements RouterStrategy {
|
||||
readonly name = "sla-aware";
|
||||
readonly description = "Selects the provider most likely to satisfy latency, error-rate, and cost SLOs";
|
||||
|
||||
select(pool, context) {
|
||||
// ... scores each candidate against policy: { targetP95Ms, maxErrorRate, maxCostPer1MTokens, hardConstraints }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**SLA fields** (set on the combo config):
|
||||
|
||||
```json
|
||||
{
|
||||
"strategy": "auto",
|
||||
"config": {
|
||||
"routerStrategy": "sla-aware",
|
||||
"slaTargetP95Ms": 1500,
|
||||
"slaMaxErrorRate": 0.05,
|
||||
"slaMaxCostPer1MTokens": 5,
|
||||
"slaHardConstraints": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**When to use**: Production workloads with strict latency, error-rate, or cost budgets.
|
||||
|
||||
**Aliases**: `sla-aware`, `sla`
|
||||
|
||||
---
|
||||
|
||||
#### 5. `lkgp` — last known good provider first
|
||||
|
||||
Tries the **last known good provider** (if set) first, then falls back to the
|
||||
`rules` strategy. Useful for session stickiness — the same provider handles
|
||||
follow-up requests in a conversation.
|
||||
|
||||
```ts
|
||||
class LKGPStrategyImpl implements RouterStrategy {
|
||||
readonly name = "lkgp";
|
||||
readonly description = "Tries last known good provider first, then falls back to rules";
|
||||
|
||||
select(pool, context) {
|
||||
if (context.lkgpEnabled === false) {
|
||||
return getStrategy("rules").select(pool, context);
|
||||
}
|
||||
|
||||
if (context.lastKnownGoodProvider) {
|
||||
const candidates = pool.filter(
|
||||
(c) => c.provider === context.lastKnownGoodProvider && c.circuitBreakerState !== "OPEN"
|
||||
);
|
||||
if (candidates.length > 0) {
|
||||
return { provider: candidates[0].provider, /* ... */ };
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to rules strategy
|
||||
return getStrategy("rules").select(pool, context);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**When to use**: Multi-turn conversations where you want the same provider to handle
|
||||
follow-up requests (e.g., for caching, context continuity, or pricing consistency).
|
||||
|
||||
**Alias**: `lkgp` (no alias)
|
||||
|
||||
---
|
||||
|
||||
### Custom router strategies
|
||||
|
||||
You can register your own `RouterStrategy` implementation via the public API:
|
||||
|
||||
```ts
|
||||
import { registerStrategy, type RouterStrategy } from "@omniroute/open-sse/services/autoCombo/routerStrategy";
|
||||
|
||||
class MyCustomStrategy implements RouterStrategy {
|
||||
readonly name = "my-custom";
|
||||
readonly description = "My custom routing strategy";
|
||||
|
||||
select(pool, context) {
|
||||
// Your routing logic here
|
||||
return {
|
||||
provider: pool[0].provider,
|
||||
model: pool[0].model,
|
||||
strategy: this.name,
|
||||
reason: "MyCustomStrategy: ...",
|
||||
candidatesConsidered: pool.length,
|
||||
finalScore: 1.0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
registerStrategy("my-custom", new MyCustomStrategy());
|
||||
```
|
||||
|
||||
Then use it:
|
||||
|
||||
```json
|
||||
{
|
||||
"strategy": "auto",
|
||||
"config": {
|
||||
"routerStrategy": "my-custom"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Router strategy selection guide
|
||||
|
||||
| Use case | Strategy | Reason |
|
||||
|---------|----------|--------|
|
||||
| Balanced workload | `rules` | Default — considers all factors |
|
||||
| Minimize cost | `cost` | Always picks cheapest |
|
||||
| Minimize latency | `latency` | Picks fastest reliable provider |
|
||||
| Strict SLOs | `sla-aware` | Filters by p95/error/cost thresholds |
|
||||
| Multi-turn chat | `lkgp` | Session stickiness |
|
||||
|
||||
SLA-aware fields:
|
||||
|
||||
```json
|
||||
|
||||
Reference in New Issue
Block a user