How the OmniRoute 12-Factor Auto-Combo System Selects Targets with Task-Aware Routing
The OmniRoute 12-factor auto-combo system routes requests to optimal model providers by detecting the task type from message content, mapping it to a capability placeholder via DEFAULT_TASK_MODEL_MAP, and scoring available candidates based on quota, latency, cost, and health metrics.
OmniRoute’s intelligent routing engine—internally codenamed I²-Factor—automates model selection through a task-aware routing layer that intercepts incoming chat requests. According to the diegosouzapw/OmniRoute source code, this system eliminates manual model selection by analyzing semantic intent and matching it against real-time provider performance data to select the best backend target.
The Three-Stage Selection Pipeline
The 12-factor auto-combo engine chains three distinct phases to resolve every request. The implementation spans open-sse/services/taskAwareRouter.ts for detection logic and src/sse/handlers/chat.ts for pipeline integration.
Stage 1: Task Detection
The detectTaskType function in open-sse/services/taskAwareRouter.ts infers semantic intent by scanning the request body for specific patterns:
- Vision cues – Any message containing
image_urlorimageparts triggers immediate classification as"vision". - System-prompt patterns – Predefined strings in system messages (e.g., “write code”, “summarize”) map to
codingorsummarization. - User-message patterns – Code fences, SQL keywords, or analytical phrasing detected in user content.
The detection follows a hardcoded precedence order—background → coding → vision → summarization → analysis → creative—ensuring the most specific intent wins. If no patterns match, the function returns "chat" and routing is bypassed.
Stage 2: Task-to-Model Mapping
Once detected, the task maps to a placeholder string via DEFAULT_TASK_MODEL_MAP:
const DEFAULT_TASK_MODEL_MAP: Record<TaskType, string> = {
coding: "auto/coding",
creative: "",
analysis: "auto/reasoning",
vision: "auto/vision",
summarization: "auto/chat:fast",
background: "auto/chat:cheap",
chat: "",
};
An empty string disables routing for that task, preserving the user-specified model. Operators can override this map at runtime via the Task-Routing Settings API (PUT /api/settings/task-routing), which persists configuration to the global object __omniroute_taskRouting_config__ and is accessed through getTaskRoutingConfig().
When enabled (config.enabled === true), the chat handler calls applyTaskAwareRouting(modelStr, body), which returns { model: placeholder, taskType, wasRouted: true } if a placeholder exists.
Stage 3: Auto-Combo Scoring
The placeholder (e.g., "auto/coding") feeds into the auto-combo resolver in src/sse/handlers/chat.ts:
const combo = await getComboForModel(resolvedModelStr);
The scoring logic, implemented in open-sse/services/combo/autoStrategy.ts, evaluates all connected providers capable of fulfilling the placeholder’s requirements. The scorer weights candidates using:
- Quota soft-penalty – Deprioritizes providers with exhausted rate limits.
- Latency/cost blending – Honors suffixes like
:fast(latency-optimized) or:cheap(cost-optimized). - Health and circuit-breaker status – Filters out unhealthy connections before scoring.
The highest-scoring candidate becomes the concrete target for the request.
Configuring Task-Aware Routing
Enable and customize routing by posting to the settings endpoint:
// PUT /api/settings/task-routing
{
"enabled": true,
"taskModelMap": {
"coding": "auto/coding",
"analysis": "auto/reasoning",
"vision": "auto/vision",
"summarization": "auto/chat:fast",
"background": "auto/chat:cheap"
},
"detectionEnabled": true
}
To disable routing for specific tasks—forcing the system to respect the user’s original model selection—set the task value to an empty string in the map.
Monitoring Routing Decisions
Each detection and routing action increments counters on the global configuration object:
config.stats.detected– Tracks how often task patterns are identified.config.stats.routed– Tracks successful overrides to auto-combo placeholders.
These metrics provide observability into how frequently the 12-factor system intervenes in request routing.
Example: Routing a Coding Request
Consider a request sent to /api/v1/chat/completions:
{
"model": "openai/gpt-4o",
"messages": [
{ "role": "user", "content": "Write a function that sorts an array in JavaScript." }
]
}
detectTaskTypematches the JavaScript reference and code intent, returning"coding".applyTaskAwareRoutingreplaces"openai/gpt-4o"with"auto/coding".- The auto-combo scorer evaluates available coding-capable models (e.g.,
openai/gpt-4o-mini,anthropic/claude-3.5-sonnet) and selects the optimal candidate based on current quota and latency data.
Summary
- The 12-factor auto-combo system automates target selection through detection, mapping, and scoring phases implemented in
taskAwareRouter.tsandchat.ts. - Task detection prioritizes vision content, then coding patterns, then analytical language, defaulting to
"chat"if ambiguous. - Model mapping uses
DEFAULT_TASK_MODEL_MAPto translate tasks into capability placeholders likeauto/codingorauto/chat:fast. - Runtime configuration allows operators to override mappings via
PUT /api/settings/task-routingand inspect routing frequency throughconfig.stats. - Scoring logic balances quota availability, latency preferences, cost constraints, and health checks to pick the best provider.
Frequently Asked Questions
How does OmniRoute detect the task type for routing?
OmniRoute scans request messages for vision content (images), system-prompt keywords, and user-message patterns like code fences or SQL syntax. The detectTaskType function in open-sse/services/taskAwareRouter.ts evaluates these cues in a fixed order—background, coding, vision, summarization, analysis, creative—to determine the most specific intent.
Can I disable task-aware routing for specific workloads?
Yes. Set the task’s value to an empty string in DEFAULT_TASK_MODEL_MAP or via the PUT /api/settings/task-routing API. For example, setting "creative": "" forces creative requests to use the user-specified model rather than auto-routing.
What happens if no task patterns match the request?
If detectTaskType finds no matching cues, it returns "chat" and the system bypasses task-aware routing. The original model specified in the request is preserved and sent directly to the auto-combo scorer without task-specific overrides.
Where is the routing statistics data stored?
Statistics are stored on the global configuration object __omniroute_taskRouting_config__, specifically under config.stats.detected and config.stats.routed. These counters increment each time a task is identified and each time a routing override is applied, respectively.
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 →