How to Configure Custom Routing Strategies in OmniRoute Beyond Built-in Options

To configure custom routing strategies in OmniRoute, implement the RouterStrategy interface with a select() method, register it via registerStrategy(), and reference it in combo configurations.

OmniRoute ships with 19 built-in routing strategies—ranging from priority and weighted to auto and lkgp—but its pluggable architecture lets you inject arbitrary decision logic. This guide explains how to extend the platform with your own routing policies, backed by the actual source code in diegosouzapw/OmniRoute.

Overview of Router Strategies in OmniRoute

According to the OmniRoute source code, routing strategies are classes that implement a single select(pool, context) method. The pool contains available providers as VirtualAutoComboCandidate objects, while context carries task metadata like LKG‑P flags and latency history.

The built-in strategy identifiers live in src/shared/constants/routingStrategies.ts. When you need behavior not covered by these 19 options—say, a custom cost‑latency threshold or domain‑specific heuristics—you create a custom implementation.

Implementing a Custom Router Strategy

To build a valid custom strategy, you need three pieces from open-sse/services/autoCombo/routerStrategy.ts:

  • The RouterStrategy interface – requires name, description, and select(pool, context)
  • The registerStrategy(name, instance) function – adds your strategy to the global runtime registry
  • The select() return format – must return an object with provider, model, strategy, and optional reason

Step-by-Step Implementation

// myCustomStrategy.ts
import {
  registerStrategy,
  type RouterStrategy,
} from "@omniroute/open-sse/services/autoCombo/routerStrategy";

class MyCustomStrategy implements RouterStrategy {
  readonly name = "my-custom";
  readonly description = "Prefer providers with latency < 200ms and cost < $0.02";

  select(pool, context) {
    // Filter out unhealthy providers first
    const healthy = pool.filter(c => c.circuitBreakerState !== "OPEN");
    
    // Apply custom business logic
    const candidates = healthy.filter(
      c => c.p95LatencyMs < 200 && c.costPer1MTokens < 0.02
    );
    
    // Fallback if no candidates match strict criteria
    const chosen = candidates.length ? candidates[0] : healthy[0];

    return {
      provider: chosen.provider,
      model: chosen.model,
      strategy: this.name,
      reason: "MyCustomStrategy applied custom latency/cost filter",
    };
  }
}

// Register during module initialization (e.g., in a plugin file)
registerStrategy("my-custom", new MyCustomStrategy());

Key implementation details to note:

  • Circuit breaker awareness – always check circuitBreakerState !== "OPEN"; the pool may contain unhealthy candidates
  • Graceful degradation – your select() should handle empty filtered sets
  • Registration timing – call registerStrategy() before any combos using it are instantiated

Registering and Activating Your Strategy

The global strategy registry in open-sse/services/autoCombo/routerStrategy.ts is a simple mutable map that accepts registrations at runtime. This design lets you extend OmniRoute without modifying core source files.

Method 1: Persisted Combo with Custom Strategy

Create a combo via API or UI that references your registered name:

{
  "id": "my-combo",
  "name": "Fast-Cheap Combo",
  "strategy": "auto",
  "config": {
    "routerStrategy": "my-custom",
    "targets": [
      { "model": "anthropic/claude-3.5-sonnet" },
      { "model": "openai/gpt-4o-mini" }
    ]
  }
}

The strategy: "auto" tells OmniRoute to use the auto-combo engine, while config.routerStrategy overrides the default routing logic with your custom implementation.

Method 2: Zero-Config Auto-Combo

For ad-hoc requests without persisted combos, force your strategy via the X-OmniRoute-Mode header:

curl -X POST http://localhost:20128/v1/chat/completions \
  -H "Authorization: Bearer <key>" \
  -H "Content-Type: application/json" \
  -H "X-OmniRoute-Mode: my-custom" \
  -d '{"model":"auto/fast","messages":[{"role":"user","content":"Explain quantum tunneling"}]}'

This flow uses open-sse/services/autoCombo/virtualFactory.ts to build an in-memory combo configuration that respects your routerStrategy setting.

Key Source Files for Custom Routing

File Purpose
src/shared/constants/routingStrategies.ts Canonical list of 19 built-in strategy identifiers
open-sse/services/autoCombo/routerStrategy.ts RouterStrategy interface, registry, and registerStrategy() export
open-sse/services/autoCombo/virtualFactory.ts Constructs ephemeral auto-combo configs; honors config.routerStrategy
src/sse/handlers/chat.ts Entry point that detects auto/ prefixes and dispatches to the auto-combo engine
docs/routing/AUTO-COMBO.md User-facing documentation on custom router strategy workflows

Advanced Customization Patterns

External decision services – Your select() can call out to ML models, cost-forecasting APIs, or load balancers before returning a provider. The context parameter receives full request metadata to support this.

Multi-factor scoring – Combine latency, cost, token‑throughput, and provider‑specific SLAs using weighted formulas in select().

A/B testing strategies – Register multiple experimental strategies and assign traffic percentages via context inspection or upstream headers.

Summary

Frequently Asked Questions

What interface must a custom routing strategy implement?

A custom strategy must implement RouterStrategy from open-sse/services/autoCombo/routerStrategy.ts, providing name, description, and a select(pool, context) method that returns a provider selection with provider, model, strategy, and optional reason fields.

When should I use a persisted combo versus the zero-config auto-combo?

Use persisted combos when you need reusable, named configurations with fixed targets and consistent routing logic. Use zero-config auto-combo with X-OmniRoute-Mode for ad-hoc requests, prototyping, or dynamic strategy selection without creating persistent resources.

Can I modify a custom strategy after registration?

Registration is additive only—you cannot unregister or replace strategies by name at runtime. To update logic, restart the OmniRoute process with a new strategy implementation registered under a different name, or version your strategy identifiers (e.g., my-custom-v2).

Does OmniRoute validate custom strategy names against the built-in list?

No. The ROUTING_STRATEGY_VALUES constant in src/shared/constants/routingStrategies.ts documents public identifiers, but the runtime registry accepts any string name. Invalid or unregistered names will cause routing failures at request time, not at startup.

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 →