# How OmniRoute Auto-Combo Scoring Works: Understanding the I2 (Inverse-Cost & Inverse-Latency) Factors

> Learn how OmniRoute's auto-combo scoring uses 12 factors like inverse cost and latency to boost cheaper and faster providers for optimal performance. Understand weighted scoring now.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: deep-dive
- Published: 2026-07-31

---

**OmniRoute’s auto-combo engine assigns each provider-model candidate a weighted score from 0 to 1, where the I2 factors (`costInv` and `latencyInv`) calculate inverse preferences that boost cheaper and faster providers according to configurable weights.**

OmniRoute’s intelligent routing system, implemented in the `diegosouzapw/OmniRoute` repository, uses a sophisticated **auto-combo scoring** mechanism to dynamically select optimal AI providers from a candidate pool. The scoring pipeline evaluates providers across **13 distinct factors**, with particular emphasis on the **I2 factors**—inverse-cost and inverse-latency metrics that penalize expensive or slow options. This article explains how these inverse factors are calculated, weighted, and integrated into routing decisions at the source code level.

## The Auto-Combo Scoring Pipeline

When a request reaches the auto-combo router, the system gathers viable `ProviderCandidate` objects and passes them to **`scorePool()`** ([[`scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/scoring.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/services/autoCombo/scoring.ts), lines 41-48). This function orchestrates a three-stage evaluation:

1. **`calculateFactors()`** (lines 20-38) gathers raw telemetry—including quota, health, cost, and latency—and normalizes every metric to the **[0..1]** range.
2. **`calculateScore()`** (lines 22-41) multiplies each normalized factor by its configurable weight and sums the products, clamping the final result to **[0..1]**.
3. The router sorts candidates by descending score and selects the top-ranked provider.

The **I2 factors** are calculated during the factor normalization stage to ensure higher values represent better performance (lower cost and latency).

## Breaking Down the I2 Factors

The **I2** abbreviation refers to the two **inverse** metrics in the scoring matrix: **Inverse-Cost** and **Inverse-Latency**. These are derived from raw telemetry to ensure the scoring algorithm maximizes preference for cheaper and faster providers.

### Inverse-Cost (costInv)

The `costInv` factor measures preference for cheaper providers using the formula:

```

1 - candidate.costPer1MTokens / maxCost

```

Where `maxCost` is the highest cost per 1M tokens found in the current candidate pool (see line 27 of `calculateFactors`). The result is passed through **`clamp01()`** (lines 24-27 of [[`scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/scoring.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/services/autoCombo/scoring.ts)) to guarantee a [0..1] output and protect against malformed telemetry. A provider with the lowest cost in the pool receives a `costInv` score of approximately **1**, while the most expensive receives **0**.

### Inverse-Latency (latencyInv)

Similarly, `latencyInv` measures preference for faster providers:

```

1 - candidate.p95LatencyMs / maxLatency

```

Here, `maxLatency` is the highest P95 latency in the current pool (see line 28 of `calculateFactors`). This normalization ensures that providers with the lowest latency (best performance) score near **1**, while slower providers approach **0**.

## Weight Configuration and Normalization

By default, the system assigns specific weights to the I2 factors via **`DEFAULT_WEIGHTS`** (lines 43-48):

- **`costInv`** = **0.15**
- **`latencyInv`** = **0.12**

These weights can be customized per combo via the UI or API. When custom weights are provided, the engine calls **`normalizeScoringWeights()`** to ensure the total sum approximates **1**, maintaining proportional scoring balance across all 13 factors.

## Impact on Routing Decisions

Because the final score is a weighted sum, the I2 factors directly influence provider selection:

- A **cheap and fast** provider will have both `costInv` ≈ 1 and `latencyInv` ≈ 1, significantly boosting its total score.
- An **expensive or slow** provider will have `costInv` ≈ 0 or `latencyInv` ≈ 0, dragging down the score even if other factors (quota, health, task-fit) are strong.

The **auto-combo engine** ([[`engine.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/engine.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/services/autoCombo/engine.ts)) orchestrates this flow, while the **pipeline router** ([[`pipelineRouter.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/pipelineRouter.ts)](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/services/autoCombo/pipelineRouter.ts)) handles final selection and fallback logic.

## Code Implementation Example

The following TypeScript example demonstrates how to score a candidate pool and inspect I2 contributions:

```typescript
// 1️⃣ Build a candidate (normally fetched from DB / live telemetry)
const candidate: ProviderCandidate = {
  provider: "openai",
  model: "gpt-4o",
  quotaRemaining: 85,
  circuitBreakerState: "CLOSED",
  costPer1MTokens: 0.028,
  p95LatencyMs: 180,
  // …other optional fields omitted for brevity
};

// 2️⃣ Score a pool of candidates
import { scorePool, DEFAULT_WEIGHTS } from "@omniroute/open-sse/services/autoCombo/scoring";
import { getTaskFitness } from "@omniroute/open-sse/services/autoCombo/taskFitness";

const pool = [candidate /*, …more candidates */];
const scored = scorePool(pool, "chat", DEFAULT_WEIGHTS, getTaskFitness);

// 3️⃣ Inspect the I2 contributions
const { costInv, latencyInv } = scored[0].factors;
console.log(`Inverse-cost: ${costInv.toFixed(2)}, Inverse-latency: ${latencyInv.toFixed(2)}`);

```

To prioritize latency over cost for a specific combo, override the weights before normalization:

```typescript
import { normalizeScoringWeights } from "@omniroute/open-sse/services/autoCombo/scoring";

const customWeights = {
  ...DEFAULT_WEIGHTS,
  costInv: 0.08,      // lower weight for cost
  latencyInv: 0.20,   // higher weight for latency
};
const normalized = normalizeScoringWeights(customWeights);

// Use `normalized` when calling `scorePool` for this combo
const scoredForCombo = scorePool(pool, "chat", normalized, getTaskFitness);

```

## Summary

- **OmniRoute’s auto-combo scoring** evaluates providers using 13 normalized factors, including the critical **I2 inverse metrics**.
- **`costInv`** and **`latencyInv`** are calculated as `1 - (value/max)` to ensure higher scores represent cheaper and faster providers.
- Default weights are **0.15** for cost and **0.12** for latency, customizable via **`normalizeScoringWeights()`**.
- The scoring logic resides in **[`open-sse/services/autoCombo/scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/scoring.ts)**, with utilities like **`clamp01`** in **[`open-sse/utils/number.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/number.ts)**.
- Final routing decisions combine these weighted scores with task-fitness and health checks to optimize provider selection.

## Frequently Asked Questions

### What does I2 stand for in OmniRoute scoring?

**I2** stands for the **Inverse-Cost** and **Inverse-Latency** factors. These are the second pair of inverse values in the scoring methodology, designed to reward providers with lower costs and lower P95 latency by inverting their raw metrics relative to the pool maximum.

### How are the I2 factor weights configured?

The default weights (**0.15** for `costInv` and **0.12** for `latencyInv`) are defined in `DEFAULT_WEIGHTS` within [`scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/scoring.ts). Administrators can override these per combo via the UI or API; the system automatically normalizes custom weight sets using `normalizeScoringWeights()` to ensure the total sums to approximately 1.

### Why does OmniRoute use inverse metrics instead of raw cost and latency?

The scoring system maximizes the final score (higher is better). By calculating inverse values (`1 - normalized`), cheaper providers receive `costInv` scores near **1** and expensive providers near **0**, allowing the weighted sum to correctly prioritize cost efficiency without requiring inverted logic in the aggregation function.

### Which source files handle the I2 factor calculations?

The core logic resides in **[`open-sse/services/autoCombo/scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/scoring.ts)**, specifically within `calculateFactors()` (lines 20-38) for metric normalization and `calculateScore()` (lines 22-41) for weighted aggregation. The `clamp01()` safety guard is implemented in **[`open-sse/utils/number.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/number.ts)**.