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
RouterStrategyinterface – requiresname,description, andselect(pool, context) - The
registerStrategy(name, instance)function – adds your strategy to the global runtime registry - The
select()return format – must return an object withprovider,model,strategy, and optionalreason
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
- Custom routing strategies in OmniRoute require implementing the
RouterStrategyinterface fromopen-sse/services/autoCombo/routerStrategy.ts - Registration happens via
registerStrategy(name, instance)before combo instantiation - Activation works in persisted combos (
config.routerStrategy) or zero-config calls (X-OmniRoute-Modeheader) - Source authority: The 19 built-ins are declared in
src/shared/constants/routingStrategies.ts; the extension API lives inopen-sse/services/autoCombo/routerStrategy.ts
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →