How the Auto Combo Routing Strategy Works in OmniRoute

The auto combo routing strategy in OmniRoute dynamically selects the best LLM provider per request through a nine-step pipeline that combines intent classification, self-healing health checks, tiered scoring, and budget enforcement.

OmniRoute's auto combo is a self-optimizing routing mode designed to eliminate static provider lists. Instead of hard-coded priorities, the engine evaluates candidates at runtime using a multi-factor scoring system. This article breaks down the complete implementation as found in the OmniRoute source code.

What Is the Auto Combo Routing Strategy?

The auto combo is one of OmniRoute's configurable routing strategies. Unlike fixed-provider combos, it builds a candidate pool at request time and applies a sophisticated selection pipeline. The strategy lives primarily in open-sse/services/autoCombo/engine.ts and draws on supporting modules for scoring, health checks, and task fitness evaluation.

The core goal: deliver cost-aware, latency-optimized, and task-appropriate provider selection without manual tuning.

The 9-Step Auto Combo Pipeline

Step 1: Intent Classification

When callers don't specify a concrete taskType, the engine infers one from the conversation context. It extracts text from the last user message and runs classifyPromptIntent to categorize the request into built-in intents: code, reasoning, simple, or medium.

This inferred intent feeds into downstream task-fitness scoring. Implementation spans lines 30-45 of open-sse/services/autoCombo/engine.ts.

Step 2: Mode Pack and Weight Resolution

Combos can specify a mode pack—predefined weight profiles like "coding" or "fast"—that override raw config.weights. The engine normalizes final weights through normalizeScoringWeights.

This allows operational profiles without per-request configuration. See lines 48-55.

Step 3: Candidate Filtering

The engine applies two filters to build the initial candidate set:

  • Pool restriction: Only providers in config.candidatePool are considered (empty pool = all providers eligible)
  • Health exclusion: The Self-Healing Manager (getSelfHealingManager) evaluates each provider; unhealthy providers are excluded and tracked in the excluded list

This filtering occurs at lines 56-68.

Step 4: Provider Scoring

Remaining candidates pass through scorePool, which combines:

Factor Source
Static attributes Cost, latency, reliability from provider metadata
Task fitness getTaskFitness result using the Step 1 intent to bias toward appropriate model families

The scoring implementation resides at lines 77-79.

Step 5: Second-Pass Self-Healing

After scoring, the Self-Healing manager re-evaluates providers using their actual scores. Any provider still deemed unhealthy is removed from consideration. This double-check prevents borderline-healthy providers from winning on score alone (lines 80-88).

Step 6: Exploration vs. Exploitation

The engine implements a configurable exploration rate (default 5%) via explorationRate. A random draw determines whether to:

  • Explore: Select any candidate randomly to gather performance data on underutilized providers
  • Exploit: Use deterministic Score-Tier Rotator selection

This trade-off between discovery and optimization appears at lines 96-104 and 98-106.

Step 7: Tiered Round-Robin Selection

When exploiting, providers are grouped into three tiers via groupIntoTiers:

  • Top tier: Highest-scoring providers
  • Mid tier: Moderate performers
  • Rest tier: Lower-scoring options

If top-tier scores exceed the rest by CLEAR_WINNER_THRESHOLD, that tier wins outright. Otherwise, the combo name itself—"smart", "fast", "cheap"—drives weighted tier selection through chooseTierWeighted.

The tier logic spans lines 52-75, 78-84, 86-94, and 108-124.

Step 8: Budget Cap Enforcement

When config.budgetCap is set, the engine:

  1. Estimates USD cost for the selected provider
  2. If over cap, seeks a cheaper alternative within budget
  3. If no compliant candidate exists, applies config.budgetFallback:
    • "cheapest": Fall back to the cheapest provider (legacy behavior)
    • "strict": Throw BudgetExceededError, failing the request

Budget handling occupies lines 108-136 and 139-149.

Step 9: Result Construction

The final SelectionResult encapsulates:

  • Selected provider and model
  • Computed score
  • Whether exploration was used
  • Scoring factors breakdown
  • Excluded providers list
  • Connection ID (when applicable)

Assembly occurs at lines 138-147.

Configuration and Usage Example

import { selectProvider, type AutoComboConfig } from '@/open-sse/services/autoCombo/engine';
import { getProviderCandidates } from '@/open-sse/services/autoCombo/providerRegistryAccessor';

// Example auto-combo configuration
const config: AutoComboConfig = {
  id: 'auto-chat',
  name: 'smart',
  type: 'auto',
  candidatePool: [],                // empty → consider all providers
  weights: { cost: 0.2, latency: 0.3, reliability: 0.5 },
  modePack: 'coding',               // optional – overrides weights
  budgetCap: 0.02,                  // $0.02 per request
  budgetFallback: 'strict',
  explorationRate: 0.05,
  routerStrategy: 'cost',
};

// Pull the current provider candidates from the registry
const candidates = await getProviderCandidates();

// Optional: raw messages for intent classification
const promptMessages = [
  { role: 'user', content: 'Write a function to merge two sorted arrays in JavaScript.' },
];

// Perform the auto selection
try {
  const result = selectProvider(config, candidates, 'default', promptMessages);
  console.log('Selected provider:', result.provider);
  console.log('Model:', result.model);
  console.log('Score:', result.score);
  console.log('Exploration:', result.isExploration);
} catch (e) {
  if (e instanceof BudgetExceededError) {
    console.error('Request exceeds budget cap:', e.message);
  } else {
    throw e;
  }
}

Key Source Files in OmniRoute

File Purpose
open-sse/services/autoCombo/engine.ts Core implementation: selection, tier rotation, budget handling, exploration logic
open-sse/services/autoCombo/scoring.ts scorePool and weight normalization utilities
open-sse/services/autoCombo/taskFitness.ts Task-specific fitness computation
open-sse/services/autoCombo/selfHealing.ts Health-checking and provider exclusion
open-sse/services/autoCombo/modePacks.ts Predefined weight profiles (coding, fast, etc.)
open-sse/services/autoCombo/providerRegistryAccessor.ts Live provider candidate retrieval
open-sse/services/autoCombo/__tests__/autoCombo.test.ts End-to-end validation suite

Summary

  • The auto combo routing strategy eliminates static provider ordering through runtime evaluation
  • Nine pipeline steps handle intent detection, health filtering, scoring, exploration/exploitation trade-offs, tiered selection, and budget enforcement
  • Self-healing health checks run twice to ensure reliability
  • Mode packs and combo names provide operational tuning without code changes
  • Strict budget fallback enables cost-guaranteed workloads

Frequently Asked Questions

How does OmniRoute's auto combo handle provider failures?

The auto combo uses a Self-Healing Manager that evaluates provider health during two separate phases. First, it filters out unhealthy providers before scoring. Second, after scoring, it re-checks remaining candidates and removes any that fail health validation. Unhealthy providers are tracked in the excluded list returned with the selection result.

What is the exploration rate in OmniRoute auto routing?

The explorationRate parameter (default 5%) controls probabilistic random selection. When triggered, the engine ignores scores and picks any candidate randomly. This gathers performance data on underutilized providers and prevents the system from over-optimizing to stale benchmarks. When not triggered, deterministic tier-based selection takes over.

Can the auto combo enforce strict budget limits?

Yes. Setting budgetCap enables cost estimation before final selection. If the chosen provider exceeds the cap, the engine seeks alternatives. With budgetFallback: 'strict', no valid candidate triggers a BudgetExceededError, failing the request rather than violating the budget. Use 'cheapest' for legacy fallback behavior instead.

How does OmniRoute determine which model fits a task?

If no taskType is provided, the engine runs classifyPromptIntent on the last user message to infer intent (code, reasoning, simple, medium). This intent feeds getTaskFitness, which biases the composite score toward providers with appropriate model families. Mode packs like "coding" further tune weight distributions for common workload patterns.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →